Synchronization in autotest


One of the most serious problems in the development autotests (especially at the level of functional GUI) is to synchronize the execution of tests with the work of the application under test. In other words, the actions that are performed in an automated test should be carried out at precisely the moment when the application is required for this action state. Otherwise, we can get a picture when the test tries to click, enter text, while the form on which to implement these actions, no. As a result, our test is beaten, but quite incomprehensible ways. Moreover, if there are no mechanisms for balancing the state, something like this could seriously lick the batch tests as a whole.

As a result, it is necessary to ensure the pace of the test so that it matches the tempo of the application under test. How to do it?

The simplest option is to set the delay. Practically in all media for automating the functional testing is a manual that just make a pause in the execution. Thus, many decisions there are functions of the form: sleep (nSec) or wait (nSec). In TestComplete is done by calling BuiltIn.Delay (), in Java for this is the challenge Process.sleep (). All these solutions have a similar structure – the only parameter that indicates the time at which to pause.

The benefits of these solutions:

  1. Simplicity – use built-in function / method is quite simple and understandable
  2. In some cases, these inserts allow you to avoid "jamming" performance when 2 rather expensive operations are performed one after another (in particular in SilkTest in some cases, wait 1 second allowed to avoid stalling instruction execution agent).
  3. Quite efficient for operations that have a fixed time "delay", for example, the appearance of the message box issued by the client script on a Web page. In this case, a pause is needed simply to clear a test sync with the moment the exact appearance of windows

Nevertheless, in this solution has its drawbacks:

  1. Irrational use of run-time – some operations, especially treatment of various client-server requests, may take different time, even for the same team. Accordingly, it is expedient to make a break for a time interval that covers the maximum waiting time. As a result, if the action was executed earlier, then pause still operates a fixed time, why we are losing up to several minutes on one such expectations. If such action would be a lot, then the total loss of run-time will be up to several hours.
  2. On various media tested application can run at different speeds, respectively, to all occurrences of instructions to pause the rebuild timeout.
  3. Such pauses do not reflect the reasons for which they bear, because of what such a code is very difficult to read. Also in the test code may be too many such statements, why the code is growing very significantly without any apparent reason
  4. Such a pause can not guarantee that the application under test has reached the desired state

Another solution is the ability to slow down the execution of automated test. One of the advantages of automatic execution of tests is the speed of execution of instructions, but often it becomes, and the main drawback, as the instructions begin to run so fast that the built-in handlers for the application under test do not have time to react, why there are many mistakes that can not be played by hand, in principle. Many more or less developed systems for automated functional testing has settings to slow down the operation text input and mouse actions. Often this is done by setting the appropriate configuration. Some decisions have special instructions governing the speed of the test. For example, in the library Watir is such a field as Watir: IE: speed, which takes the values: slow or: fast, depending on what type of execution speed, we want to ask. Selenium RC has an analog – a method setSpeed ??main client class. What this approach has advantages:

  1. Simplicity – in this case is sufficient in a single place to configure the speed of
  2. Ability to adjust the tests under real rate of work, which provides the user
  3. Optimal amount of software code testing – no need to install ubiquitous pauses in the code is enough to put down only to actions taken

Part of the shortcomings of the previous method (prostanovka pauses) is eliminated with this approach, but nevertheless some of them are still relevant:

  1. Irrational use of run-time – much of the delay in this approach may prove impractical, as a result we can also neutralize the advantage of test automation as a high-speed performance. For example, we need to fill in several fields, and then click on the button. Fields would be convenient to perform at a normal pace, when they fill up quickly, not pausing a second or more. At this point we’re losing a lot of time
  2. Practically does not stabilize the work when you run queries, occupying a rather arbitrary execution time. In fact, this approach does not solve completely the problem of synchronizing operations with a fairly wide range of execution time.
  3. There is no guarantee that the application under test has reached the desired state

Thus, this approach is more or less viable except for local applications, in which at least debugged navigate windows.

Both of the above approach does not solve one problem – the control of the state of the application. But this is a very important moment, as if the application came from a state in which a capacity test, the actual execution of the test loses its meaning and it must be either stop or restore the desired state. But it would first need to diagnose that the application under test start to behave abnormally. To resolve this problem, there are various methods that interrogate the application under test. For example, all means of automated functional testing at the GUI are in the arsenal of functions / methods that verify the existence of an object. It’s usually kind of methods Exists (in SilkTest, RFT, Waitr – method, TestComplete – this property), win_exists, obj_exists (WinRunner) or something like isElementPresent, as implemented in SeleniumRC. These solutions verify the existence of an element. Accordingly, synchronization in this case, implements the following algorithm:

bObjFound = false;
02 
03while( !timeOutExeeded ) {
04        if( elementPresent( element ) ) {
05 
06              bObjFound = true;
07              break;
08        }
09 
10        verifyTimeOut();    
11}
12 
13if( !bObjFound ) {
14        Error( "No object available" );
15}

The above pseudo-code works on the principle of circularity of the test until then, until the desired item or until the maximum waiting time will come. Maximum waiting time – is a quantity which is determined depending on the speed of application execution. Often, it’s estimated lead time of a typical request during normal operation of the system. A similar pattern was originally built to test the download pages. In particular in Watir is a method such as Watir:: IE.wait. In the present methods SeleniumRC waitForFrameToLoad, waitForPageToLoad, waitForPopup etc.

Since these solutions allow you to monitor the presence of certain objects, it largely allows you to monitor the change of application state, as in many state of the application is determined by the presence or absence of a window or element. But there is a more general case in which the change of application state can be expressed in a change of state of an object. That is, we need to wait until an object reaches the state. In TestComplete there is a method WaitProperty, which most clearly reflects the interface for such solutions. This method has the form:

1 obj.WaitProperty (propertyName, propertyValue, timeOut)

This method returns True, if the property name is specified in the propertyName takes the value specified in propertyValue before it will timeout timeOut. Otherwise, it returns False. Such a solution can be achieved and other means of self-test (and, it is useful to have in the arsenal of analogues). In this case synchronization is reduced to checking the transition to the desired state (or rather the transition of a control element to the desired state).

Of course, this will increase the amount of code, but at the same time:

  • self-test performed no more than necessary (as soon as the desired event occurs, the test run goes on)
  • clearly reflect the transition between states
  • Since the point of verification is bound to clear this state, we can give informative error message if the application is not transferred to the desired state
  • improves code readability, since by such a point of verification, we can compare the test code with the expected state of the system

These were the most common methods for solving the synchronization problem. Using the most effective solutions will vdalneyshem simplify development and testing support, especially given the fact that during the development of approximately 60% of the errors autotests fall to synchronization errors. Therefore the correct approach to solving synchronization problems in the early stages of the comparison was automation will significantly reduce the cost of supporting tests.

See Also

    Advertising

    Archives