Forum Discussion

altemann's avatar
altemann
Contributor
9 years ago

How to slow down the execution of the test in a specific part of the script?

Hello,

I was wondering...Is there any possible way to slow down Testcomplete for a while during a script execution?

 

I've tried slowing down the execution using the Project\Playback\Delay Between Events property, but what I really need is something that slows down the execution only when I want, for as long as I want (sometimes I need to slow down the execution during a whole window test because it works slower than the rest of the system, so Delay() is not an option either) then go back to the original speed.

 

It would be something like this:

 

//"Normal" speed

field.SetText("Text");

field.SetText("Text");

 

//Enters "slow" speed

field.SetText("Text");

btnOK.Click();

wnd.Close();

...

 

//Back to normal speed

field.SetText("Text");

 

So, is there any way to get this done?

Thanks in advance!

  • I agree with tristaanogre there is probably a more effective and direct way of fixing this by just adding Delays exactly where they are needed.

     

    But if you are determined to find a way to slow down sections of a script there's a potential hackish way of doing it. If you are familiar with Events you could use OnLogEvent and have it execute a Delay statement depending on whether a global variable you set in your script is True or False. That way when you want the script to slow down you set the global variable to True and every time a Log.Event occurs it will perform a Delay of whatever length you want, effectively slowly down your script on every statement that interacts with the UI [Keys, Click, etc.]. This should work more or less the same as the project property setting does.

  • I agree with tristaanogre there is probably a more effective and direct way of fixing this by just adding Delays exactly where they are needed.

     

    But if you are determined to find a way to slow down sections of a script there's a potential hackish way of doing it. If you are familiar with Events you could use OnLogEvent and have it execute a Delay statement depending on whether a global variable you set in your script is True or False. That way when you want the script to slow down you set the global variable to True and every time a Log.Event occurs it will perform a Delay of whatever length you want, effectively slowly down your script on every statement that interacts with the UI [Keys, Click, etc.]. This should work more or less the same as the project property setting does.

    • altemann's avatar
      altemann
      Contributor
      This (Events + Global variable) solved my problem! Never thought of that! Thanks a lot!!
    • tristaanogre's avatar
      tristaanogre
      Esteemed Contributor

      Not a bad solution at all, ghuff2.  Perhaps a combination of the two... implement the event handler for executing the delay call (the event can even be expanded for other functions... throw a case statement into it to check for different global variable values) but still use the nested "for" loops.

       

      Generally speaking, a best practice for automated testing is to separate your test data from your test code. That way, altering the data you use for the test isn't as invasive of a code change. I personally use CSV files completely external to the project so, if I want to change a test, I just drop in a different file. Code still executes as always, but now the test code is more flexible and can be reused.

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    OK... the obvious question... why do you need to do this?

    I mean, the EASY answer to your question is to simply hard code delays into your script using Sys.Delay(nnn).  Is there a reason why this would not work?

    A smarter method would be to use a "wait" method of some sort (see the article here) or add some logic where you would check for some sort of condition before going on to the next step.  Looking at the script code you gave as the example, my guess is that after the last "SetText", something changes on the screen that you need to slow down and wait for (button being enabled, calculation completed, etc) that, if the test runs full speed, errors will occur because conditions aren't ready to take the next step.

    • altemann's avatar
      altemann
      Contributor

       

      OK, first of all, thanks for the quick reply! Let's see if I can explain this better.

       

      I have a test unit that includes a lot of stuff in many different window (fast-working windows) and then another screen pops up and I have to work at it checking all the information and even adding more info - that runs me about 160 lines of code. The problem is: This last window is WAY slower than the rest of the windows. Every action at it takes around 2~4 seconds to be entirely processed. 

       

      • WaitProcess/WaitWindow is not an option in this case because the screen is always "ready" for TestComplete, but it's still processing the last info when TC tries to input the next action. I've been through all the properties of the fields and the window checking if I can find anything that can give me that "waiting" state from TC but couldn't find anything...
      • 100+ delays are going to ruin the code!! But it can be done as a last option.

       

      Anyways, thanks again.

      • tristaanogre's avatar
        tristaanogre
        Esteemed Contributor

        What makes that second form so much slower?  Also... 160 lines of code?!?!

        A suggestion that will not add 100 delay calls and may reduce your code overhead... have you considered creating an array or table of the data that you need to input and then using a while loop or some such thing to iterate through the table when you get to that screen to input the data?  Two bonuses on this: first, it will GREATLY reduce your code overhead as you'll reduce the number of code lines and shift the data out of the code and into a seperate table that can be more easily manipulated.  And secondly, for that part that needs the delay, you'd only have to write out ONE delay line rather than 2.  Here's some pseudo code to kinda give you the idea...

        TableVar1 = <some sort of data table or data source for the values of your first form>;
        TableVar2 = <data table or source for the values of your second form>;
        
        Form1.Activate;
        For i = 1 to TableVar1.length do
        { 
        Field.SetText(TableVar1.Value(i); if i = <value where the second form comes up> then {
        For j = 1 to TableVar2.length do {
        NewField.SetText(TableVar2.Value(j));
        Sys.Delay(4000);
        } ButtonOnForm2.Click(); Form2.Close();
        }
        }

        It's kind of rough but hopefully you get the idea.