Information in this topic applies to desktop applications only. |
Connected and Self-Testing applications are deprecated. These technologies will be removed in one of the future releases of TestComplete. To create test code that runs from within your tested apps, use TestLeft, a SmartBear functional testing tool for developers. |
This topic describes how to create Self-Testing Applications with the following compilers:
- Visual C++ 7.x (unmanaged code)
- Visual C++ 2005 (unmanaged code)
- Visual C++ 2008 (unmanaged code)
- Borland C++Builder 6.0
- CodeGear C++Builder 2009
- Embarcadero C++Builder 2010 and XE
Currently, it is not possible to create Self-Testing Applications in managed Visual C++. |
Creation of a C++ Self-Testing Application includes three steps:
- Preparing your C++ project
- Writing test code in your C++ Self-Testing Application
- (Optional) Writing code in your TestComplete project
The description of each step is below. As you will see, the creation of a Self-Testing Application is very similar to creating a Connected Application. The key difference is that the Self-Testing Application should run test code in a separate thread (see below).
Preparing your C++ project
-
Open an existing project or create a new one in your development tool (C++Builder or Visual C++).
-
If you use Visual C++, disable optimization:
-
In Visual C++ 7.x, 2005 and 2008:
-
Right-click the project in the Solution Explorer and select Properties from the context menu to display the Project Properties dialog.
-
Switch to the Configuration Properties | C/C++ | Optimization node and select Disabled (/Od) from the Optimization combo box.
-
Click OK to close the dialog.
-
-
-
C++Builder users should disable the Code Guard:
-
Select Tools | CodeGuard Configuration from the main menu to display the CodeGuard Configuration dialog.
-
Uncheck the Enable box on the Preferences tabbed page.
-
Click OK to save the changes.
-
-
Include the following header file in the source file(s) where you want to insert TestComplete C++ script procedures:
Header file Scripts <TestComplete>\Connected Apps\C++\script.h for Microsoft Visual C++ and Borland C++Builder For instance,
C++
#include "..\..\..\Connected Apps\C++\script.h"
-
Place this directive before the script code in each file where you will add TestComplete scripts:
C++
using namespace TestComplete;
This will resolve a possible conflict of names (
Sys
,Log
, etc.)
Writing Test Code in C++ Self-Testing Applications
-
Include the following header file in the source file(s) where you want to insert TestComplete C++ script procedures:
Header file Scripts <TestComplete>\Connected Apps\C++\script.h for Microsoft Visual C++ and Borland C++Builder For instance,
C++
#include "..\..\..\Connected Apps\C++\script.h"
For more information on the Script.h file, its classes and functions, see Creating Connected Applications in C++.
-
Place this directive before the script code in each file where you will add TestComplete scripts:
C++
using namespace TestComplete;
This will resolve a possible conflict of names (
Sys
,Log
, etc.) -
Now, initialize the COM libraries by inserting a call to the
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
macro in the main thread of your application. For instance:C++
...
using namespace TestComplete;
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
...This macro is declared in the script.h file. It will initialize COM libraries and create global variables that provide access to TestComplete internal objects:
Log
,Sys
,Regions
, etc.In order to use this macro in Visual C++, you should either define the
_WIN32_DCOM
constant or define the_WIN32_WINNT
constant to be greater than or equal to 0x0400.You only have to use this macro once in the main thread of your code. If your application calls this macro twice, an error will occur.
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
initializes COM for the multi-threaded object concurrently (using theCOINIT_MULTITHREADED
value). If you have already initialized COM in your application for an apartment-threaded object concurrently (COINIT_APARTMENTTHREADED
), you should use a similar macro -IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
. Otherwise, using theIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
macro will cause an error. Also, if you have already initialized COM for a multi-threaded object concurrently, a call toIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
will cause an error. It is recommended to use a multi-threaded model (thexxxx_MTA
macro).If you use the
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
macro (notxxxx_MTA
), or if you do not use any of the macros at all, you should initialize COM yourself (see step 8). -
Create a separate thread for the procedure to run in, unless it does not call for onscreen inputs (e.g. button clicks, menu selections, etc.) serviced by the current thread.
If you have not yet initialized COM using the
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
macro in the main thread, you should initialize it now by using one of the following ways:-
Place a call to the
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)
function at the beginning of your thread, and a call toCoUninitialize()
at the end of your thread. -
Declare a variable of the
COleInit
type. The classCOleInit
is declared in script.h. Its constructor calls theCoInitializeEx
function, and the destructor callsCoUninitialize
. The variable will be destroyed (the destructor will be called) when the thread finishes and COM will be uninitialized when testing is over.
Note that the
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
orIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
macros initialize both COM libraries and global variables used to access TestComplete internal objects. If you do not use these macros, you may need to update your scripts. -
-
Copy one or more test routines from TestComplete C++ scripts to your application source. Of note, normally test routines use the p and
w
variables. When imported to a C++ application, they become variables of thevar
type. TheCOleInit
variable, which is used to initialize COM, should be declared before anyvar
variables, otherwise, an error will occur. If you do not use theCOleInit
variable, you should assignNULL
to allvar
variables before COM is uninitialized. For example:C++
var p, w;
...
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
...
p = NULL; // <-- Correct
CoUninitialize();
w = NULL; // <-- Incorrect!!!
// This should be done before CoUninitialize
... -
Write the test code into your C++ source, or copy one or more test functions from TestComplete C++ scripts.
The script.h file only contains variables for standard TestComplete objects (
Sys
,Log
,Regions
,Files
and others). If you need to work with objects that are provided by third-party plugins, you should obtain this object in your code by using theGetObjectByName
function that is defined in the script.h file:C++
[script.h]
var GetObjectByName(const BSTR ObjName)
For more information on writing test code, see Creating Connected Applications in C++.
-
In order for the test code located in a Self-Testing Application to run successfully, TestComplete must be in the script-running mode. To run the test code, you should either launch the Self-Testing Application from the TestComplete script, or call the
RunTest
routine (see Running Connected and Self-Testing Applications for more information).If you are going to use the
RunTest
routine, insert a call to it before the first statement of the test code in your Self-Testing Application. To stop the test run initiated withRunTest
, use theStopTest
routine:C++
RunTest("My Test", "MyProject", "C:\\Work\\MyProjectSuite.pjs");
...
// Test code
...StopTest();
If you are going to launch your Self-Testing Application from TestComplete, call the test procedure from your own code. For instance, you can call the test procedure within a button’s
OnClick
event handler. - Compile your application.
Writing Code in TestComplete Projects
In order for Self-Testing Application to be able to use TestComplete scripting objects and post messages to the test log, TestComplete must be in the script-running mode. The testing engine switches to this mode when you run a test from TestComplete, or when you call the RunTest
routine (see Running Connected and Self-Testing Applications).
If you do not use the RunTest
routine, you should launch your Self-Testing Application from TestComplete. To do this:
-
Open your project in TestComplete.
-
Add your Self-Testing Application to the project’s tested applications list. For more information on how to do this, see Defining Applications to Test.
-
Write script code that will launch your Self-Testing Application and wait while it performs the testing actions. For instance:
JavaScript, JScript
function Test()
{
var p;
// Launches the Self-Testing Application and obtains the process
// that corresponds to your Self-Testing Application
p = TestedApps.Items[0].Run();
// Delays script execution while
// the Self-Testing Application performs the testing actions
while(p.Exists)
aqUtils.Delay(500);
}Python
def Test(): # Launches the Self-Testing Application and obtains the process # that corresponds to your Self-Testing Application p = TestedApps.Items[0].Run() # Delays script execution while # the Self-Testing Application performs the testing actions while p.Exists: aqUtils.Delay(500)
VBScript
Sub Test
' Launches the Self-Testing Application and obtains the process
' that corresponds to your Self-Testing Application
Set p = TestedApps.Items(0).Run
' Delays script execution while
' the Self-Testing Application performs the testing actions
While p.Exists
aqUtils.Delay 500
WEnd
End SubDelphiScript
procedure Test;
var
p : OleVariant;
begin
// Launches the Self-Testing Application and obtains the process
// that corresponds to your Self-Testing Application
p := TestedApps.Items[0].Run;
// Delays script execution while
// the Self-Testing Application performs the testing actions
while p.Exists do
aqUtils.Delay(500);
end;C++Script, C#Script
function Test()
{
var p;
// Launches the Self-Testing Application and obtains the process
// that corresponds to your Self-Testing Application
p = TestedApps["Items"](0)["Run"]();
// Delays script execution while
// the Self-Testing Application performs the testing actions
while (p["Exists"])
aqUtils["Delay"](500);
} -
Make sure this code is called when running the current TestComplete project.
-
As you can see, the script runs until the Self-Testing Application is closed. In order to stop the script run from the Self-Testing Application, use the
Runner.Stop
method. This method notifies TestComplete that the test run is over and refreshes the Test Log so that it displays the latest test results.
You can now run the test by clicking the button whose OnClick
event handler contains the test code.
See Also
Self-Testing Applications
Running Connected and Self-Testing Applications
Connected Applications - Overview
Creating Connected Applications in C++