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. |
A Connected Application simulates mouse or keyboard input into itself. Before trying this, please see the Creating Self-Testing Applications in C++ topic. This topic describes how to create a “generic” Connected Application using 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 Connected Applications in managed Visual C++. |
The examples described in this topic are not self-testing as they explain how to “test” MS Paint. Although, you may want to read this topic first before going to the self-testing topic.
Creation of a C++ Connected Application includes three steps:
- Preparing your C++ project
- Writing test code in your C++ Connected Application
- (Optional) Writing code in your TestComplete project
The description of each step is 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:
-
Rightlick 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++ Connected Applications
-
Add the macro
IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
to your code. This macro is declared in the script.h file where it initializes COM libraries and creates global variables that provide access to internal TestComplete objects -Sys
,Log
,Regions
, etc. Note that you should use this macro only once in the main thread of your code. If your application calls this macro twice, an error will occur.IMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
initializes COM libraries for apartment-threaded object concurrently (using theCOINIT_APARTMENTTHREADED
value). If you have already initialized your application for multi-threaded object concurrently (COINIT_MULTITHREADED
), you should use theIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS_MTA
macro instead of theIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
. Otherwise, a call toIMPLEMENT_TESTCOMPLETE_GLOBAL_OBJECTS
will cause an error.In order to use the MTA macro in Visual C++, you should define either the
_WIN32_DCOM
constant or the_WIN32_WINNT
constant so that it is greater than or equal to 0x0400. Like the non-MTA macro, the MTA macro should be used only once in your code. -
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)
See also note on writing test code below.
-
In order for the test code located in a Connected Application to run successfully, TestComplete must be in the script-running mode. To run the test code, you should either launch the Connected 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 Connected 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 Connected 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.
Note that the script.h file overloads the "[ ]", "( )" and "=" operators for scripting objects to refer to their properties and methods:
Function | Description |
---|---|
TestedApps["RunAll"](); |
Calls the RunAll method of the TestedApps object. |
Sys["Process"]("MSPAINT"); |
Returns the MSPAINT process. |
Log["Message"]("My text"); |
Posts the My text message to the test log. |
Sys["Desktop"]["ActiveWindow"]()["Name"]; |
Returns the Name property of an active window. |
Sys["Child"](0); |
Returns the first child of the Sys object. |
Note that besides TestComplete, script.h allows you to work with other COM servers (e.g. with MS Word) in the same manner. script.h simplifies the syntax used in C++ applications to work with COM servers via late binding. Once you have obtained the IDispatch
interface of the desired server, you can address its methods and properties using the C++Script syntax rather than calling the GetIDsOfName
, Invoke
and other methods. See Writing C++Scripts for more information.
The notation used in TestComplete to refer to object properties and methods via C++ scripts is possible because an object is treated as an associative array, which is a data structure that associates data values with strings. In arrays the index operator ("[]") is used to get access to array elements, in objects it is the property name specified as a string.
To set the value of a property, use the following syntax:
C++, C++Script
Sys["Desktop"]["ActiveWindow"]()["WndCaption"] = (var)"New Caption";
If the property is indexed, you can use any of the following notations:
C++, C++Script
p["Form1"][Put("PropertyName")](Index) = Value;
// or
p["Form1"][(Put)"PropertyName"](Index) = Value;
C++, C++Script
p["Form1"][Put("PropertyName")](Index1, Index2) = Value;
// or
p["Form1"][(Put)"PropertyName"](Index1, Index2) = Value;
C++, C++Script
p["Form1"][Put("PropertyName"), 1, "2nd index"] = Value;
// or
p["Form1"][(Put)"PropertyName"](Index1, "2nd index") = Value;
TestComplete supports properties with up to 10 indexes. If you use more, please contact our support team.
The following code illustrates how to obtain the property value:
C++, C++Script
// Indexed property
v = p["Form1"]["PropertyName"](1, "2nd index");
// Simple, unindexed property
w = p["Form1"]["PropertyName"];
script.h holds a declaration for the var
type. It was developed as an alternative to the standard VARIANT
type. var
makes it easier to work with objects and their properties in C++ scripts. For instance:
C++, C++Script
w = Sys["ActiveWindow"]();
Log["Message"](w["Name"]);
TestComplete routines work only with OleVariant data types. Values of this type can be converted to any other data type. Conversions are generally automatic, but in some cases the compiler does not have sufficient information about the type to convert it. When this happens, you will get an error message reading: “Ambiguity between 'CVariantWrap::operator A' and 'CVariantWrap::operator B' ”. The solution is to force the conversion to the desired type. For example,
C++, C++Script
if (bool(w["Exists"]) && bool(w["VisibleOnScreen"])) // Correct
Writing Code in TestComplete Projects
In order for Connected 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 Connected Application from TestComplete. To do this:
-
Open your project in TestComplete.
-
Add your Connected 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 Connected Application and wait while it performs the testing actions. For instance:
JavaScript, JScript
function Test()
{
var p;
// Launches the Connected Application and obtains the process
// that corresponds to your Connected Application
p = TestedApps.Items[0].Run();
// Delays script execution while
// the Connected Application performs the testing actions
while(p.Exists)
aqUtils.Delay(500);
}Python
def Test(): # Launches the Connected Application and obtains the process # that corresponds to your Connected Application p = TestedApps.Items[0].Run() # Delays script execution while # the Connected Application performs the testing actions while(p.Exists): aqUtils.Delay(500)
VBScript
Sub Test
' Launches the Connected Application and obtains the process
' that corresponds to your Connected Application
Set p = TestedApps.Items(0).Run
' Delays script execution while
' the Connected Application performs the testing actions
While p.Exists
aqUtils.Delay 500
WEnd
End SubDelphiScript
procedure Test;
var
p : OleVariant;
begin
// Launches the Connected Application and obtains the process
// that corresponds to your Connected Application
p := TestedApps.Items[0].Run;
// Delays script execution while
// the Connected Application performs the testing actions
while p.Exists do
aqUtils.Delay(500);
end;C++Script, C#Script
function Test()
{
var p;
// Launches the Connected Application and obtains the process
// that corresponds to your Connected Application
p = TestedApps["Items"](0)["Run"]();
// Delays script execution while
// the Connected 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 Connected Application is closed. In order to stop the script run from the Connected 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
Connected Applications - Overview
Creating Event Handlers in Visual C++ Applications
Creating Event Handlers in Delphi and C++Builder Applications
Running Connected and Self-Testing Applications
Self-Testing Applications
Creating Self-Testing Applications in C++