Testing Applications That Require Rebooting

Files

Applies to: TestComplete 8

Typically, while creating functional tests, you record a sequence of actions performed against your tested application and then verify that the actual result equals the expected one. However, you may also need to create tests that not only perform actions over an application, but also automate the application installation process. These tests are very helpful when you need to test the application deployment, installation and execution processes. Such a test, for example, may copy the installation files to a computer, install the application and then execute another test against the installed application automatically. Quite often, installation programs require rebooting the computer to complete the installation successfully. This article describes how you can create tests for such installation programs with TestComplete. It contains the following sections:

How to Reboot the System

As it was mentioned above, the typical example of an application that may require rebooting the computer is an installation program. So, while testing such programs, you will have to decide how to reboot the system. Two possible approaches include:

  • Rebooting with the tested application (for instance, when a reboot is needed, installation programs display a dialog or message box asking “Do you want to restart now?”. You can restart the computer by clicking Yes in this message box), or

  • Rebooting automatically from your TestComplete test by using a special TestComplete method — aqEnvironment.RebootAndContinue. The following JScript snippet demonstrates how to call this method after changing the system language (as you may know, this procedure requires rebooting in order for the change to take effect):

    // TestComplete JScript code

    function ChangeSystemLanguage()
    {
      aqEnvironment.LanguageForNonUnicodePrograms = "French";
      aqEnvironment.RebootAndContinue("Unit1.Proc1", "Password1", "UserName1");
    }

    Here, Unit1.Proc1 is the script routine that will be run after the reboot. Password1 and UserName1 are the credentials for logging in to the operating system after the reboot. For detailed information on the method and its parameters, see the method description in the TestComplete help.

So, you can reboot the computer using either of the mentioned approaches. Although, these approaches perform the same actions (reboot the system), there are some differences between them. For example, the ways how these approaches assist you in solving problems that may occur before and after restarting the system are different. So, let’s examine these problems and learn how to solve them using each of the approaches described above.

  1. Closing TestComplete correctly.

    If you are rebooting the system from the tested application, TestComplete (or another important application) will be forced to close. So, some necessary project and log files may not be saved or may be saved incorrectly.

    If you are using the RebootAndContinue method, the test saves all the project contents correctly before closing TestComplete.

  2. Logging in to the system after the computer is restarted.

    After rebooting, you will have to log in to the operating system. You can change the security settings on your machine to omit logging in to the system or automate this process somehow. Of course, you can log in manually every time the application has rebooted the system. However, it may be very inconvenient due to a variety of reasons. For example, you may test the installation that reboots the system, and the test may be executed at night (as tests are usually executed). So, you will have to solve the problem with logging in for such tests in some way.

    Using the RebootAndContinue method, you can easily solve this problem. For this purpose, you just need to pass the needed user name and password to this method as parameters. This feature helps you work around the rebooting problem easily.

  3. Continuing the test execution after rebooting.

    Suppose that you need to install an application and then continue testing it after rebooting. If you have rebooted the system from the tested application, you will have to create an additional test and execute it in some way after the computer restarts.

    If you choose to reboot with TestComplete’s RebootAndContinue method, you simply need to pass the needed script routine name to it. TestComplete will automatically launch this script routine after rebooting.

As you can see, the RebootAndContinue method greatly simplifies both rebooting the computer from your tests and solving all the problems described above. So, this article describes how to use the RebootAndContinue method. However, quite often, you cannot use this method “as is” to automate user actions over installation programs that require rebooting. It is necessary to perform certain additional actions to automate them. We will describe these in the next section of the article.

How Rebooting Works

Some installation programs require not only rebooting the system, but also starting right after the reboot is finished to complete the installation successfully. To implement this behavior, the applications add values to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce registry key.

When the operating system starts, it checks the values of this key and launches the applications specified by these values. The operating system launches the applications one by one in the order of their appearance in the registry. The operating system waits until the launched application has performed all the expected actions and then proceeds to the next value in the list.

As you may know, a similar registry key (RunOnce) exists in the registry under the HKEY_CURRENT_USER node (HKEY_CURRENT_USER \SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce). This key has a lower priority as compared to the LOCAL_MACHINE’s RunOnce key, and its values are processed after the LOCAL_MACHINE values have been processed.

TestComplete’s RebootAndContinue method uses the CURRENT_USER RunOnce key. This causes problems with testing installation programs that typically add values to the LOCAL_MACHINE RunOnce key. So, by default, the tested application will be launched before TestComplete. TestComplete will be launched later and will be unable to test the application.

To solve the problem, we can create a test script which will add a value for running TestComplete to the LOCAL_MACHINE RunOnce key. This value should be the first one in the key in order for TestComplete to be launched before other applications “mentioned” in the key. This will guarantee that TestComplete will be running at the moment the tested application starts. We’ll describe such script code’s creation later in this article.

Note that we should also remove the value added by the RebootAndContinue method to the CURRENT_USER RunOnce key. Without removing this value, the operating system will attempt to launch another TestComplete instance. The TestComplete engine does not allow this (only one TestComplete instance can be running at a time), so it will display an error message that may make problems for the test run.

How to Start TestComplete After Rebooting

The values in the RunOnce key specify the command lines of the applications to be run. As you may know, TestComplete supports several command-line arguments that let you specify the project suite or test project to be opened and the test to be launched.

Now, the important point is that we must not specify this command line in the value to be added to the RunOnce key. The problem is that the operating system processes values one by one and will not go to the next value until the application launched by the previous value has performed all the expected actions. So, if we specify the TestComplete command line in the value, the operating system will not launch the tested application until TestComplete has executed the test.

To solve this problem, we recommend that you create a JScript file (.js) that will use the WshShell scripting object to launch TestComplete asynchronously (the WshShell scripting object is provided by the operating system). The operating system will execute this .js file quickly and will proceed with other values without “pausing” upon TestComplete. We’ll consider creating this file later in this article.

General Procedure

Keeping in mind the problems described above, we’ll create script code that will perform the following actions:

  1. Add a value for running TestComplete to the LOCAL_MACHINE RunOnce registry key. This value will be the first among other values of the key, and it will run not TestComplete, but the .js file that will launch TestComplete.
  2. Create a .js file for launching TestComplete. This file will also delete the registry value added by the RebootAndContinue method (this file is the right place to do this as it is the first file launched by the OS after restarting).
  3. Insert calls to the created script routine and the RebootAndContinue method into your test.

In the following sections of the article we will describe how to perform these actions.

Modifying Registry Values

This section provides instructions on how to access the RunOnce registry key from your test and modify these values to make TestComplete be launched first. This task is compound, and it comprises the following steps:

  1. Obtaining a list of the values that are currently stored in the RunOnce registry key and storing them to an array.
  2. Deleting all the values from the RunOnce registry key.
  3. Modifying the array of values so that the array’s first element is the value launching TestComplete.
  4. Saving new values to the RunOnce key.

Now, let’s create the script code that will perform these actions automatically. First, we will go through this code step-by-step and see what each part of this code does. After that (at the end of this section), we will merge all of the described snippets to one script routine.

To get access to the RunOnce registry key, use TestComplete’s built-in program object:

var runOnce = Storages.Registry("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", HKEY_LOCAL_MACHINE);

Note that the usage of the Registry method depends on your operating system’s registry view (32-bit or 64-bit). For more information on this method’s parameters, see the method description in the TestComplete online help.

After you get access to the registry key, you can iterate through the list of values stored in the RunOnce registry key (the key from the HKEY_LOCAL_MACHINE root registry key) and save these values to an array:

for (var i = 0; i < runOnce.OptionCount; i++)

{
  Name = runOnce.GetOptionName(i);
  items[Name] = runOnce.GetOptionByIndex(i, "DEFAULT_VALUE");
}

Now, we will delete all the values from the RunOnce registry key. We do this to “clear” the key to make the value, which will “run” TestComplete, be added to this key as the first value. To remove all the values from the key, we will use the following code:

for (i = runOnce.OptionCount - 1; i >= 0; i--)
  runOnce.RemoveOptionByIndex(i);

The next step is modifying the RunOnce key’s values. The first value will point to the .js script file that will launch TestComplete. Other values will be copied from the list that we read from the registry earlier:

// Add a new item to the array of the registry values
var newItems = new Array();
newItems["TCRebootAndContinue"] = "C:\\Script\\StartTC.js";
for (i in items)

  newItems[i+1] = items[i];

Now, we are ready to save the new values to the RunOnce registry key. For this purpose, we will use the following code:

// Updates the list of the RunOnce key’s values
for (i in newItems)

  runOnce.SetOption(i, newItems[i]);

The entire script routine looks like this:

// TestComplete JScript code

// Modify the list of the RunOnce key’s values
function ModifyRunOnceKey()
{
  var runOnce = Storages.Registry("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", HKEY_LOCAL_MACHINE);
  var items = new Array();
  for (var i = 0; i < runOnce.OptionCount; i++)
  {
    Name = runOnce.GetOptionName(i);
    items[Name] = runOnce.GetOptionByIndex(i, "DEFAULT_VALUE");
  }

  for (i = runOnce.OptionCount - 1; i >= 0; i--)
    runOnce.RemoveOptionByIndex(i);

  Log.Message("The primary values of the RunOnce registry key are:");
  for (i in items)

    Log.Message(i + ": " + items[i]);

  // Add a new item to the array of the registry values

  var newItems = new Array();
  newItems["TCRebootAndContinue"] = "C:\\Script\\StartTC.js";
  for (i in items)
    newItems[i+1] = items[i];

  Log.Message("");
  Log.Message("The modified values of the RunOnce registry key are:");

  // Post the new items to the test log
  for (i in newItems)
    Log.Message(i + ": " + newItems[i]);

  // Update the list of the RunOnce key’s values
  for (i in newItems)
    runOnce.SetOption(i, newItems[i]);
}

You can find it in the sample TestComplete project suite that goes with this article. You can download it using the link at the top of the article, on the right.

Important: If you are using a 64-bit operating system, you must use an additional parameter to call the Storages.Registry method in the code above. So, you need to use the following line:

// Access the values of the RunOnce key
var runOnce = Storages.Registry("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", HKEY_LOCAL_MACHINE, AQRT_64_BIT);

Creating a Script File to Launch TestComplete

Now, let’s create the JScript file that will launch TestComplete from the registry. For this purpose, open any text editor and enter the code below to it. After that, save the file as StartTC.js. In this article, we suppose that you save it to the C:\Script folder.

// The StartTC.js file
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.RegDelete("HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\TestComplete4");

// Wait until the computer connects to the network
WScript.Sleep(120000); // Time in milliseconds
WshShell.Exec("C:\\Program Files\\Automated QA\\TestComplete 8\\Bin\\TestComplete.exe
\"C:\\TestCompleteProjects\\MySuite.pjs\"");

This file not only launches TestComplete, but also deletes the value which TestComplete’s RebootAndContinue method adds to the RunOnce key under the HKEY_CURRENT_USER node.

As you can see, after deleting the registry value, the script waits for 2 minutes and then launches TestComplete with the needed project suite opened (in our example, it is MySuite.pjs). These 2 minutes are needed for the system to establish connection to the network and find the License Manager PC running in it. Otherwise, TestComplete may fail to find the license, and an error will occur.

Notes:

  1. You can download the StartTC.js file to your computer. The download link is at the top of this article, on the right.
  2. The path to the TestComplete executable file may be different on different computers and operating systems. So, when running this code on your workstation, make sure that the path is correct. Otherwise, the specified script code will not be able to launch TestComplete.

Assembling the Entire Script Code and Running the Test

Now, we are ready to assemble all the code snippets described above into the entire code that will perform the following actions:

  • Modify the RunOnce registry key values (so, it starts TestComplete first after the rebooting is finished).
  • Reboot the system by calling the RebootAndContinue method from the test.
  • Launch TestComplete after the reboot is finished and continue testing the installation program. For this purpose, TestComplete will execute the ContinueTest procedure.

Note that you should add the code below to the TestComplete project that performs the install and reboots the system. Your test must contain a call to the Main function (see the code below) after the application has performed all the required actions and is “ready for rebooting” (for example, when it displays the message asking whether you want to reboot the system). After that, your test must refuse rebooting from the tested application (for example, by clicking No in the message) and perform the reboot from TestComplete (by calling the Main function).

So, the entire test for this approach looks like this:

// TestComplete JScript code

function Main()
{
  try
  {
    // Perform some actions that cause the reboot
    // Refuse rebooting from the application
    //…

    // Modify the list of the RunOnce key’s values
    ModifyRunOnceKey();

    // Reboot the system
    // After the reboot, TestComplete will execute
    // the ContinueTest() procedure under the specified account
    aqEnvironment.RebootAndContinue("Unit1.ContinueTest","Password1", "UserName1");
  }
  catch(exception)
  {
    Log.Error("Exception", exception.description);
  }
}

// …

Note: You can also download TestComplete’s project suite that contains the entire code of this sample to your computer. For this purpose, use the link in the menu in the top-right corner of this article.

Before running the code above, make sure that:

  1. The path to the .js file is correct. In the code above, we supposed that the StartTC.js file is located in the C:\Script\ folder. If it is located in another folder on your machine, specify the correct path to this file in the ModifyRunOnceKey function’s body.
  2. The StartTC.js file contains the correct paths to the TestComplete executable file (it is different in different operating systems) and to the project suite that reboots the system.
  3. The correct account is specified as a parameter of the RebootAndContinue method. Do not forget to enter the needed password and user name instead of the Password1 and UserName1 strings in the code of the Main routine.
  4. All the needed functions (ModifyRunOnceKey, and so on) are defined in your test. To download the entire code of this sample, click the link in the top-right corner of this article.
  5. The correct registry view is used. If you are using a 64-bit operating system, you must call the Storages.Registry method in the code above with an additional parameter. So, you should use the following line in the ModifyRunOnceKey function:

var runOnce = Storages.Registry("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", HKEY_LOCAL_MACHINE, AQRT_64_BIT);

After that, run your test from TestComplete.

Conclusion

We hope this article helps you create more powerful tests that can deploy applications on the tested machines automatically. If you already have TestComplete installed, make sure that you have downloaded the latest version of TestComplete from our Client Services portal. If you haven’t used TestComplete yet, download and try it for free.