Logging Capabilities

(For more resources related to this topic, see here.)

Posting messages to the log

TestComplete allows committing various types of messages to the log: ordinary messages, warnings, logs, and so on.

In this section, we will consider examples of how to use these messages.

Getting ready

Create a file with the name myfile.txt in the root directory of C:.

How to do it...

In order to see examples of all the message types in the log, the following steps should be performed:

  1. Create and launch the following function:

    function testMessages() { Log.Event("An event", "Event additional Info"); Log.Message("A message", "Message additional Info"); Log.Warning("A warning", "Warning additional Info"); Log.Error("An error", "Error additional Info"); Log.File("C:\\somefile.txt", "A file posted to the log"); Log.Link("C:\\somefile.txt", "A link to a file"); Log.Link("http://smartbear.com/", "HTTP link"); Log.Link("ftp://smartbear.com/", "FTP link"); }

    In the result, we will get the following screenshot of the log

How it works...

In the given example, we have used four different types of messages. They are as follows:

  • Log.Event: This message is an event which occurs when TestComplete interacts with a tested application. Usually, messages of this type are placed into the log at the point of text input or mouse-clicks; however, we can also place custom-made events into the log.
  • Log.Message: This message is an ordinary message that is usually used for prompting a user concerning current actions that are being executed by the script (usually, of a higher level than that of the events; for example, creation of a user, searching for a record, and so on).
  • Log.Warning: This message is a non-critical error. It is used in case the results of the check are different from those expected; nonetheless, execution of the script can carry on.
  • Log.Error: This message is a critical error usually used when an error is a critical one, making any further execution of the test would be futile

These four types of message are based on several parameters. The first of them is a string that we observe in the log itself; the second one contains additional information which can be seen in the Additional Info tab, if the message has been clicked on. The second parameter is optional and can be omitted as well as all other parameters.

There are two more types of messages:

  • Log.File: This message copies the assigned file into the file with the log, and places a reference-pointer to it. Meanwhile, TestComplete renames the file to avoid naming conflicts, leaving only the original extension intact.
  • Log.Link: This message places a link to the web page or a file, without making a copy of the file itself in the folder with the log. On clicking on the link, the file will open with the help of the associated program or a link in the browser.

These two types of message accept the link as the first parameter, and then the message parameters, and those pertaining to the additional information (as the previous four). Only the first parameter is mandatory.

Posting screenshots to the log

Sometimes, it is necessary to place an image into the log; often, it may be a window screenshot, an image of a controls element, or even that of the whole of the screen. To this end, we use the Log.Picture method.

In this section we will consider different ways to place an image into the log.

How to do it...

The following steps should be performed to place an image to the log:

  1. First of all, we will create two image objects for the enabled window and the whole of the screen:

    var picWindow = Sys.Desktop.ActiveWindow().Picture(); var picDesktop = Sys.Desktop.Picture();

  2. The image of the active window, now being stored in the picWindow variable , will be placed into the log, unchanged:

    Log.Picture(picWindow, "Active window");

  3. The image of the desktop is reduced by four times via the Stretch method , and then saved on to the file with the help of the SaveToFile method:

    picDesktop.Stretch(picDesktop.Size.Width/2, picDesktop.Size.Height/2); picDesktop.SaveToFile("c:\\desktop.png");

  4. Now we go about creating a new variable of the Picture type, loading up an image into it from the earlier saved file, and then placing the same into the log:

    var pic = Utils.Picture; pic.LoadFromFile("c:\\desktop.png"); Log.Picture(pic, "Resized Desktop");

  5. As a result of function's execution, the log will contain the two images placed therein: that of the enabled window at the moment of test execution, and that of the reduced desktop copy.

How it works...

The Log.Picture method has one mandatory parameter that is, the image itself; the other parameters being optional.

Images of any of the onscreen objects (of a window, of a singular controls element, of the desktop) can be obtained via the Picture method. In our example, with the help of the method, we get the image of the desktop and that of the active window. Instead of the active window, we could use any variable that corresponds to a window or a controls element.

Any image can be saved onto the disk with the help of the SaveToFile method. The format of the saved image is determined by its extension (in our case, it is the PNG).

If it's necessary to obtain a variable containing the image from the file, we are supposed to create an empty variable placeholder with the help of the Utils.Picture property , and then with the help of the LoadFromFile method , we upload the image into it. In the future, one could handle the image as any other, received with the help of the Picture method.

Great-size images can be minified with the help of the Stretch method. The Stretch method uses two parameters: the new width and height of the image. With the help of the Size.Width and Size.Height properties , we could zoom in or out on the image in relation to its original size, without setting the dimensions explicitly.

There's more...

With the help of the Picture method , we could obtain not only the image of the whole window or a controls element, but just a part of it. For example, the following code gets an image of the upper left square of the desktop within the sizing of 50 x 50 pixels:

var picDesktop = Sys.Desktop.Picture(0,0, 50, 50);

The values of the parameters are as follows: coordinates of the left and right top corner, and its width and height.

There is one important project setting which allows automatic posting images in case of error. To enable this option, right-click on the project name, navigate to Edit | Properties, click on Playback item from the list of options, and enable checkbox Post image on error.

Apart from changing the dimensions of the image, TestComplete allows for the execution of several, quite complicated imaging manipulations. For example, the comparison of the two images (the Compare method ), searching for one image inside the other (the Find method ), and so on. Click on the following link to get to know more about these possibilities:


Creating folders in the log

In some cases, it is useful to conceal some of the messages in the log in such a way that they are not seen all the time, rather than have them be easily accessible. For example, in case of looping through the lines of the table to locate the needed one, we could place each indexed line into the log; however, they could be rather a lot in number, making it unnecessary to view them on the top-level all the time.

To resolve this issue, TestComplete extends a possibility to create special folders in the log, where the messages could be successfully placed.

How to do it...

The following steps should be performed to create folders in the log:

  1. For creation of the new folder in the log, the method of Log.CreateFolder is to be used, the folder name expected to be passed as a parameter:

    var folder = Log.CreateFolder("1st folder");

  2. Now, for the sake of appropriating all the messages into the folder, it is necessary to enable the same with the help of the method of Log.

    PushLogFolder: Log.PushLogFolder(folder); Log.Message("This message will appear in the 1st folder"); Log.Event("This event will appear in the 1st folder");

  3. To close the current folder and revert to the previous one, the method of Log. PopLogFolder is to be utilized:

    Log.PopLogFolder(); Log.Message("This message will appear in the root folder");

    In the result, the log will assume the shape and form as shown in the following screenshot:

How it works...

The method of Log.CreateFolder returns an integer (Folder ID), which uniquely identifies the folder. With the help of the Log.PushLogFolder method , we enable the folder, whose Folder ID has been signified as a parameter.

The folder can be nested inside each other as many times as necessary, thus segregating the information in the log by levels (low-level operations will be the most nested, while the operations of the upper level will be nested above).

Such an approach is really handy, for example, in the case that each test provides a number of steps. Each step will be located on the upper level, while the details of the operations will be hidden out of view. Using such an approach, if an error has emerged, it is easy to see all of it at once: what stage did the error spring up on, since (in case of error generation in the nested folder) the sibling elements are also displayed with an error sign, or with a warning sign, depending on the type of error generated.

Remember to maintain consistency between PushLogFolder and PopLogFolder, otherwise your results will be pushed to a wrong folder and it will be difficult to find the necessary information in the log!

There's more...

If you need to send a one-off message into the closed folder, it is not necessary to open it and then close it. All the message methods of the log accept an optional parameter of Folder ID, with the help of which one could place messages into the assigned folder. For example, if we had a folder created, as in the previous example, we can place a message into it in the following manner:

Log.Message("Posting message to the specified log folder", null, pmNormal, null, null, folder);

Here, we pass only the message priority (pmNormal) and the folder identifier (folder), all the optional parameters are set to null, which implies that default values will be used.

Changing log messages' appearance

If you are unhappy with the standard font style and color in the log, they can be changed with the help of the log's attributes. In this section, we will deal with outputting the message with changed parameters for the font.

How to do it...

To post a message with a different style perform the following steps:

  1. Create a new object with the help of the Log.CreateNewAttributes method and change the following parameters: Bold, FontColor, and BackColor in the following manner:

    var attrBoldBlue = Log.CreateNewAttributes(); attrBoldBlue.Bold = true; attrBoldBlue.FontColor = clWhite; attrBoldBlue.BackColor = clBlue;

  2. Now we will evoke the method of Log.Message and, with the fourth parameter, we will pass the created variable of attrBoldBlue to it:

    Log.Message("Customized message", null, pmNormal, attrBoldBlue);

    In the result, the message will get outputted into the log as follows:

How it works...

With the help of the attributes, we can change the color of the fonts and the background (the properties FontColor and BackColor) and the text decoration (Bold, Italic, Underline, and StrikeOut).

In TestComplete, there is a set of supported standard font colors (such as clWhite and clBlue), which can be used as settings for the font and background color. Similarly, it is possible to change the text display style for other types of messages (errors, warnings, and so on) also.

Assessing the number of errors in the log

TestComplete allows you to retrieve the number of errors for the current test item (with the help of the Log.ErrCountproperty ); however, there is no way of finding out the total number of errors in all the executed tests. Such a possibility can be useful only if a certain predefined number of errors is treated as critical, upon reaching which test execution should be stopped altogether.

How to do it...

First of all, we will add two new variables on the level of Project Suite as follows:

  1. Right-click on the name of the Project Suite (in the Project Workspace toolbar, to the left) and navigate to Edit | Variables.
  2. On the Temporary Variables list, right-click on the New Item menu item.
  3. In the Name field, input the name of the ErrorsTotal variable , into the field Type select Integer, and set the Default Value field to 0.

    This variable will be a counter of the errors.

  4. Similarly, add the variable with the name of ErrorsMax. As Default Value, set the number of errors which should signal stopping test execution (in our example, those are equal to 3).

    In the result, we will have two new variables created, as shown in the following screenshot:

  5. Now we will create a handler for the OnLogError event , which will increase the counter of the errors. For this purpose, perform the following steps:

    1. Add the Events element to the project, if it is still missing (right-click on the name of the project and navigate to Add| New Item| Events).
    2. Navigate to Events| General Events on the element. In the result, the events panel will be opened.
    3. In the right section of the panel (the Events to Handle column), unfold the element of General Events and highlight the event of OnLogError.
    4. Click on the button New inside the OnLogError element.
    5. In the opened window New Event Handler, select the module in which you will store the event handler, and then click on the OK button.
    6. In the result, we will have an empty function created with the name of GeneralEvents_OnLogError.
    7. Change the function in the following manner:

      function GeneralEvents_OnLogError(Sender, LogParams) { ProjectSuite.Variables.ErrorsTotal += 1; if(ProjectSuite.Variables.ErrorsTotal > ProjectSuite.Variables.ErrorsMax) { Runner.Stop(); } }

    8. Now we will write a simple function which will create 10 error messages in the log:

      function testErrorsCount() { for(var i = 0; i < 10; i++) { Log.Error("Error #" + i); } }

    9. If we launch the testErrorsCount function now we would see that upon the fourth emergent error, test execution would be stopped, since the number of arisen errors exceeded the preset value of the ErrorsMax variable.

How it works...

In the OnLogError events handler, we increase the number of emerging errors each time the error is generated in the log (no matter how: either with the help of the method Log.Error or via TestComplete in itself, the event will be processed all the time).

When the number of errors exceed the preset threshold, we stop execution of the tests with the help of the Runner.Stop method.

To the variables on the level of Project Suite there exists access from any project. Therefore it is unimportant how exactly tests are launched: from the Project Suite, or just a project or several separate functions. In any case, the variable will be updated each time an error occurs.

It's worthwhile to note, if you have several projects running in Project Suite, each one of them should contain some sort of handler. To this end, it is much easier to create such a handler in one project and in the other projects add an existing module (by right-clicking on the Script element , thus opting for the Existing Item menu item in the Add menu). This allows us to avoid code duplication.

There's more...

In the same manner, one could trace the number of other messages (Event, Warning, File, and so on), since for each of them there exists a corresponding property, containing their number in the current test item (Log.EvnCount, Log.WrnCount, Log.FileCount, and so on).

Changing pictures' format

In TestComplete, there are several components and processing images such as testing log, region checkpoints, and Visualizer. In all the cases, TestComplete uses a specific image format for storing pictures.

In this section we will learn the ropes concerning the alteration of these images' format, which TestComplete is processing.

How to do it...

In order to change pictures' format we need to perform the following steps:

  1. Navigate to Tools | Options and open the group of Engines in the General options. Here in the Images group, the currently used format is displayed (for example, PNG).
  2. Click on the Configure button in the Images group.
  3. In the opened Image Settings window, opt for the necessary format.
  4. In the group of Format Configuration options, set other parameters for the selected image (for example, quality or depth of the color gamut).

  5. Click on OK.
  6. Now TestComplete will use the currently selected format.

How it works...

TestComplete supports four image formats, each of them having certain advantages and shortcomings as follows:

  • BMP: This is the uncompressed format, used in cases where we need precision in imaging. The major drawback of this format is its humongous size.
  • JPEG: This is the most thrifty format (form the viewpoint of the size of the file); however, its image can be less precise.
  • PNG: This is a better trade-off in-between quality and size criteria and is usually used when you need to have images with lossless compression.
  • TIFF: This is used in specific cases (for example, for typography), if it's necessary for the project in a certain case.

For the vast majority of cases, the variant with the PNG format is of a greater avail than others.

There's more...

If, in majority of the cases, you are better off with one of the economizing formats (PNG or JPEG), and it is seldom you need to create precise images in the BMP format, you can still change the format of the images on the fly.

The following example demonstrates creation of a screenshot with the use of the following two differing formats:

function testPirtureFormat() { Options.Images.ImageFormat = "BMP"; Log.Picture(Sys.Desktop.Picture(), "BMP screenshot"); Options.Images.ImageFormat = "PNG"; Log.Picture(Sys.Desktop.Picture(), "PNG screenshot"); }

Comparing screenshots with dynamic content

Let's suppose you need to compare windows images or those of controls elements with some dynamic contents (that is, if part of the image is being changed every time). This could be the case when a given controls element displays current date or time. In this situation, the image would be different every time; nonetheless, there is a way to resolve this holdup.

Getting ready

First we will do some preparations:

  1. Launch Calculator Plus in the standard mode (navigate to View | Standard).
  2. Add the element of b(right-click on the name of the project and navigate to Add | New Item | Stores).
  3. Add the element of Regions to your project (right-click on Stores and navigate to Add | New Item | Regions).
  4. Launch the following code (it will create an image of the main calculator window in Regions):

    var wCalc = Sys.Process("CalcPlus").Window("SciCalc"); Regions.AddPicture(wCalc.Picture(), "Calculator");

  5. Enter any digit to the calculator (different from the data inputted initially at the moment of image creation) and launch the following code:

    var wCalc = Sys.Process("CalcPlus").Window("SciCalc"); Regions.Compare("Calculator", wCalc.Picture());

  6. In the result, we will get the error The regions are not equal.

How to do it...

Now we are going to prepare the image so that we can compare it by performing the following steps:

  1. Open the Calculator file in any graphic editor (for example, Paint), which was created via the method Regions.AddPicture(it is located in the folder with the project, subfolder to Regions).
  2. Select any color which is not used in the window (for example, green).
  3. Fill out the upper-left pixel of the image with this color.
  4. With the same color, fill out all the dynamic area (in our case, the whole of the text field).

  5. Save the image and launch the following script:

    var wCalc = Sys.Process("CalcPlus").Window("SciCalc"); Regions.Compare("Calculator", wCalc.Picture(), true);

  6. In the result, in the log, we will see the message The regions are the same.

How it works...

If the Transparent parameter (the third parameter of the Regions.Compare method ) would be set to true, TestComplete reads the color of the upper-left pixel of the image and interprets the same as transparent, that is, does not include the areas of the color in the check.

As a result, the images are considered the same, although a part of them is different.

There's more...

Sometimes, it is not sufficient to add transparent areas, for example, if the dynamically changing data appears in different parts of the screen.

To resolve the task, the Regions.Compare method has another parameter, namely that of Tolerance. This should be an integer number, which is the maximal number of the different pixels. In this case, TestComplete will assume that images are the same, unless the number of the differing pixels exceeds the value of the Tolerance parameter.


Thus in this article we covered several topics related to TestComplete log including working with screenshots. We also discussed frequently used log features and issues one may face while working with TestComplete.

Resources for Article:

Further resources on this subject:

You've been reading an excerpt of:

TestComplete Cookbook

Explore Title