TestComplete 6 FAQ - Objects, Files and Images Comparison
This page contains answers to frequently asked questions about TestComplete ver. 4 - 6. For answers to questions on TestComplete 3, see TestComplete 3 FAQ.
Q.: I need to compare an object in the beginning, and then compare it again at the end. How would I go about doing that?
A.: First, define the property collection to compare and save this collection using the Objects.Save method. The property collection will be added to the Stores | Objects project item. Then, you can
change the object’s properties and call Objects.Compare
to compare them with values you have saved. Below there is a sample
routine. Note that you must compile your application as an Open
one in order to have access to the object’s properties:
[VBScript] Dim w, PropertyNames, CollectionName Set w = Sys.Desktop.ActiveWindow ' Prepares the property list PropertyNames = "Top Left Height Width" ' Sets the name of a property collection CollectionName = "ActiveWindowProps" ' Saves values of properties specified in PropertyNames. ' Note that the Save method also has the fourth parameter ' that does not let you save certain properties. Objects.Save w, CollectionName, PropertyNames ... ' Compares property values If Not Objects.Compare(w, CollectionName) Then Log.Message "Properties have been changed." End If
[JScript]
var w, PropertyNames, CollectionName;
w = Sys.Desktop.ActiveWindow();
// Prepares the property list
PropertyNames = "Top Left Height Width";
// Sets the name of the property collection
CollectionName = "ActiveWindowProps";
// Saves values of properties specified in PropertyNames.
// Note that the Save method also has the fourth parameter
// that does not let you save certain properties.
Objects.Save(w, CollectionName, PropertyNames);
...
// Compares property values
if (! Objects.Compare(w, CollectionName))
Log.Message("Properties have been changed.");
[DelphiScript]
var
w, PropertyNames, CollectionName : OleVariant;
begin
w := Sys.Desktop.ActiveWindow();
// Prepares the property list
PropertyNames := 'Top Left Height Width';
// Sets the name of the property collection
CollectionName := 'ActiveWindowProps';
// Saves values of properties specified in PropertyNames.
// Note that the Save method also has the fourth parameter
// that does not let you save certain properties.
Objects.Save(w, CollectionName, PropertyNames);
...
// Compares property values
if not Objects.Compare(w, CollectionName) then
Log.Message('Properties have been changed.');
end;
[C++Script, C#Script]
var w, PropertyNames, CollectionName;
w = Sys["Desktop"]["ActiveWindow"]();
// Prepares the property list
PropertyNames = "Top Left Height Width";
// Sets the name of the property collection
CollectionName = "ActiveWindowProps";
// Saves values of properties specified in PropertyNames.
// Note that the Save method also has the fourth parameter
// that does not let you save certain properties.
Objects["Save"](w, CollectionName, PropertyNames);
...
// Compares property values
if (! Objects["Compare"](w, CollectionName) )
Log["Message"]("Properties have been changed.");
Q.: Is it possible to capture an image or a screen while executing the script for later comparison?
A.: Yes. Scripts can save images using the Regions.AddPicture method.
The saved image
will be automatically added to the Regions collection of the Stores project item. To compare images, use the Regions.Compare
method:
[VBScript]
Dim w1
Set w1 = p.Window("MyWindowClass", "MyWindowCaption", 1)
w1.Activate
Regions.AddPicture(w1, "MyAppWnd")
. . .
If Not Regions.Compare("MyAppWnd", w1) Then
Log.Warning "The window " & w1.FullName & " was changed!"
End If
[JScript]
var w1 = p.Window("MyWindowClass", "MyWindowCaption", 1);
w1.Activate();
Regions.AddPicture(w1, "MyAppWnd");
. . .
if (! Regions.Compare("MyAppWnd", w1) )
Log.Warning ("The window " + w1.FullName + " was changed!");
[DelphiScript]
var w1 : OleVariant;
. . .
w1 := p.Window('MyWindowClass', 'MyWindowCaption', 1);
w1.Activate;
Regions.AddPicture(w1, 'MyAppWnd');
. . .
if not Regions.Compare('MyAppWnd', w1) then
Log.Warning ('The window ' + w1.FullName + ' was changed!')
[C++Script, C#Script]
var w1 = p["Window"]("MyWindowClass", "MyWindowCaption", 1);
w1["Activate"]();
Regions["AddPicture"](w1, "MyAppWnd");
. . .
if (! Regions["Compare"]("MyAppWnd", w1) )
Log["Warning"]("The window " + w1["FullName"] + " was changed!");
Note: If the TestComplete 3 Compatibility plug-in is installed, TestComplete emulates functionality of the earlier versions of the product and the Regions object contains methods and properties from TestComplete 3 and
this new functionality is not available. In this case use
the Regions.SaveToFile method instead of Regions.AddPicture.
See the "Comparing and Finding Images" help topic for more information.
Q.: I save the object using Objects.Save and some properties, for instance, Items (TStrings type), are not saved. Is there any way to save these properties?
A.: The Objects object can only save properties
of simple types (integer, string, and so on), TestComplete’s engine works
with TStrings via IDispatch, and thus,
properties of the TStrings objects are not saved.
For instance, if you need to save tree view items, Objects
will not save you from writing the save and retrieve code yourself.
The code below illustrates how you can save TreeView
items. This example assumes that the application displays a form
with a VCL TListView control on it, and this
list view is passed to SaveItems as its first parameter.
SaveItems first retrieves all treeview items and
saves them as text under the filename specified as the last parameter.
Next, SaveItems compares this file with another one
(hard-coded) and reports directly to the Log whether
the treeview contents have changed. Note that the application
under test must be compiled as an Open Application. To start testing,
run the MainTest procedure in TestComplete.
[DelphiScript]
procedure SaveItems(LV : OleVariant; FileName : string);
var
i, j : Integer;
s : string;
F : TextFile;
Node : OleVariant;
begin
AssignFile(F,FileName);
Rewrite(F);
try
for i := 0 to LV.Items.Count - 1 do
begin
Node := LV.Items.Item[i];
s := Node.Caption;
Log.Message(s);
Writeln(F,s);
{ If you use PRegister to prepare the Open Application,
use the following line }
for j := 0 to Node.SubItems.Count-1 do
{ If you work with the Debug Info Agent™,
the TStrings.Count property is invisible
to TestComplete (see Debug Info Restrictions).
You have to call the read method of
the Count property directly.}
for j := 0 to Node.SubItems.GetCount-1 do
begin
{ If you use PRegister to prepare the Open Application,
use the following line. }
s := Node.SubItems.Strings.Strings[j];
{ If you work with Debug Info Agent™,
the TStrings.Strings property is invisible to TestComplete.
You have to call its read method directly.}
s := Node.SubItems.Strings.Get(j);
Writeln(F,s);
end;
Writeln(F,'');
end;
finally
CloseFile(F);
end;
// Compares two files
if not Files.Compare(FileName, 'ListViewContents.txt') then
Log.Error('ListView has changed', '', pmHighest)
else
Log.Message('OK', '', pmLower);
end;
procedure MainTest;
var
p, w: OleVariant;
begin
TestedApps.RunAll;
p := Sys.Process('Project1');
w := p.Form1;
w.Activate;
SaveItems(w.ListView1,'c:\Work\Test1.txt');
end;
Q.: Is there any way to prevent the failure of bitmap comparisons from changes in screen resolution or color depth?
A.: The screen resolution should not affect image comparison results if the size of the windows remain the same (in pixels). That is, if the image size changes, there is nothing you can do in TestComplete to prevent the failure.
For color depth, the image comparison engine is able to perform automatic color conversion and compare images that have different color depths. However, sometimes the changes in color depth may cause Windows to draw objects differently. TestComplete cannot ignore these changes and the comparison fails.
To make sure the test works correctly, you can set the screen resolution and color depth from your script. Below is a sample script that demonstrates how to do this:
[VBScript]
Sub TestSetDisplay
Call SetDisplay(800, 600, 32)
MsgBox "SetDisplay(800, 600, 32)"
Call SetDisplay(1024, 768, 32)
End Sub
' This function changes display settings:
' x, y - screen resolution
' d - color depth
Function SetDisplay(x, y, d)
Dim dm, dwLastError
SetDisplay = -1
Set dm = Win32API.DEVMODE
If (Win32API.EnumDisplaySettings(VarToInteger(0), -1, dm) <> 0) Then
dm.dmPelsWidth = x
dm.dmPelsHeight = y
dm.dmBitsPerPel = d
SetDisplay = Win32API.ChangeDisplaySettings(dm, 0)
Else
dwLastError = Win32API.GetLastError()
Log.Error("Error code: " & dwLastError)
End If
End Function
Q.: Regions.Compare indicates that the images are different even though they look the same. What is wrong?
A.: Most likely you used the JPEG format. This format uses lossy compression to reduce the size of the original image, even if high compression quality is set. To avoid the problem we recommend that you use the BMP or PNG format instead of JPEG.
Q.: Can I use TestComplete to compare PDF files?
A.: Currently, there are no features for comparing Adobe PDF files. However, you can use one of the following solutions:
Files.Compare method. This can help reveal files that have different size, creation date and other physical attributes. See the "File Checkpoints" help topic for details.
Picture.Compare or Regions.Compare methods or via the Region Checkpoints. See the "Comparing and Finding Images" help topic for more information.
In order for Adobe Reader to be recognized as an MSAA application, you need to perform the following steps:
- Make sure that the MSAA plug-in is installed on your computer. You can do this in the Install Extensions dialog (File | Install Extensions).
- Open the Project Properties window (right-click your project in Project Explorer and select the Edit | Properties context menu item).
- Select the Open Applications | MSAA category and enable the * item in the List of accepted windows.
Once this is done, TestComplete exposes every object that supports the IAccessible interface. This significantly increases the number of objects that are available to TestComplete and you now have the ability to access individual parts of the document: paragraphs, lists, headers and so on. Each of them is represented as a separate MSAAObject and you can retrieve the fragment’s text via the Value property.
However, due to a great number of objects, it becomes difficult to locate the desired element. For example it can have a name like: Sys.Process("AcroRd32").Window("AcrobatSDIWindow", "aTestFile.pdf - Adobe Reader", 1).Window("AVL_AVView", "AVToolBarHostView", 1).Window("AVL_AVView", "AVInternalDocumentView", 1).Window("AVL_AVView", "AVSplitterView", 2).Window("AVL_AVView", "AVPageView", 4).MSAAObject("client").MSAAObject("editable_text").
In this situation it is convenient to locate the needed element with the Finder tool of the Object Properties window. Alternatively you can use a similar tool in the Create Property Checkpoint dialog. This dialog generates code that verifies the value of the specified property, but the code can easily be modified for the comparison goals.
