In my Project Suite I have a "Core" project which houses my testing API that interfaces to my AUT, as well as all of the shared project items (Name Mapping, Events, Stores, etc.). Then I use other Projects to house tests for several different types of test runs. The Test projects reference the API Interface units. What I like to call "Interface Units" allow me to abstract the complexity of normal object mapped TestComplete code away from the test script itself. this allows anyone on the team to easily understand what the test is doing and what Assertions are being made. The goal in each test unit is to limit the amount of messy object mapping code and only make calls to the Interface functions.
Interface units in the Core project must be referenced to any other project that
needs them which does add a bit of work, but I found that work spent
developing an API to our AUT was much better than using TC in its more
simplistic testing approach.
Suite
- Core (API project)
- Script
- Interfaces
- IRibbon (Interface Unit)
- SelectTab()
- ETabType()
- R1 (test project)
- Script
- Interfaces
- IRibbon (Referenced Interface Unit)
- Tests
- SetManualCalibrationValue (Test Unit)
- SetManualCalibrationValue()
- R2 (test project)
- Script
- Interfaces
- IRibbon (Referenced Interface Unit)
In the sample code I gave you before, the scope of EnumTabType() is limited to when the IRibbon.SelectTab() function is called, so it is in the same unit. These Classes can be set up in any unit you want to use to pass the Class around, so long as its been referenced in the project, then in the test unit. The scope works the same as for any other variable you might use. In my project I use other custom classes and objects in other Interface units in the Core project. i.e. IVariables - Where I have clusters of variables that are needed throughout the test environment, grouped by uses.
Here is an example of the end result. It is very clear what references the script uses, what is being called, and what the test is doing. It is this same methodology allows custom classes and objects to be passed between each of my different test projects.
//USEUNIT IAppRunClose
//USEUNIT IAssert
//USEUNIT IDataSourceSelect
//USEUNIT IRibbon
//USEUNIT ISourceStartStop
//USEUNIT IComputations_PowerEnergy
//USEUNIT IDock_Results
//USEUNIT IUtilities
function SetManualCalibrationValue()
{
var _calValue = 100, _calUnit = 'J', _totalSci = '1.000e+02', _source = 'beammaker';
IAppRunClose.BGRestart();
IDataSourceSelect.SelectDataSource(_source);
ISourceStartStop.SourceStop();
IRibbon.SelectTab(new ETabType().Computations());
IComputations_PowerEnergy.SetCalibrationValue(_calValue);
IComputations_PowerEnergy.SetCalibrationUnit(_calUnit);
IComputations_PowerEnergy.EnableCalibration();
var _total = IDock_Results.getTotalEnergyString();
var _units = IDock_Results.getTotalEnergyUnits();
IAssert.assert_IsEqual(_total, _totalSci, "Total does not match: \n" +_total+ "\n" +_totalSci);
IAssert.assert_IsEqual(_units, _calUnit, "Unit does not match: \n" +_units+ "\n" +_calUnit);
_calValue = 200, _calUnit = 'W', _totalSci = '2.000e+02';
IComputations_PowerEnergy.SetCalibrationValue(_calValue);
IComputations_PowerEnergy.SetCalibrationUnit(_calUnit);
IComputations_PowerEnergy.EnableCalibration();
Delay(1000);
_total = IDock_Results.getTotalEnergyString();
_units = IDock_Results.getTotalEnergyUnits();
IAssert.assert_IsEqual(_total, _totalSci, "Total does not match: \n" +_total+ "\n" +_totalSci);
IAssert.assert_IsEqual(_units, _calUnit, "Unit does not match: \n" +_units+ "\n" +_calUnit);
IAppRunClose.BGClose();
IUtilities.LogCount();
}
Sorry to drag on but did I give you all the answers you were looking for? The downside of this approach is how large the project suite gets, where every project has to reference all of the interface units, but it gives me the functionality and robustness that I need.