If you ever looked at the EasyRepro samples, you’ve probably seen a lot of calls to the ThinkTime method. Here is an example – basically, you do something useful in the test.. and, then, you add ThinkTime:
What ThinkTime does – it’s just puts current execution thread on hold for the specified number of milliseconds:
Hm.. you probably did not want your test to spend useful automation time sleeping, right? Well, of course you can take a nap, too, but that definitely looks suspicious.
So, what is the purpose of this? First of all, let’s remember that we are using EasyRepro (and, therefore, Selenium) for UI testing. When an actual user goes to Dynamics to do something, that user will never be doing everything with the speed of a robot talking to the computer through a wired interface – instead, there will be mouse movement time, there will be unexpected browser slowdowns, there will be urgent phone calls that will break the flow, etc. So, if the purpose of our UI test were to emulate user actions, then it would be only reasonable to introduce some delays.
Still, that would be a good explanation, but is there a technical reason, too?
When I was looking into it, my first thought was that, possibly, it’s required to ensure that, whatever javscript event handlers are there in Dynamics, we are giving them enough time to run before we do anything else. However, right now I think it’s not the main reason. There is no multithreading in JavaScript, yet both UI and programmatic events are handled on the same main thread. So.. If we use EasyRepro to set a value of any particular field, all required event handlers will be added to the queue right away, and, if we do anything else in our test code, that action will be added to the queue right after the event handlers. Since EasyRepro is, actually, using a programmatic interface (for instance, you won’t see mouse movements while running the test.. you can actually keep doing something on a different screen/in a different application while the test is running), those events will just be added to the queue.
Actually, I just went to one of the sample tests (“CreateNewAccount”) and removed all ThinkTimes. That version of the test worked just fine, too:
See that message on the left which is saying “Test Passed”? Now let’s think of what was happening in that test:
- We have emulating user login
- We have navigated to Sales->Accounts
- We have changed the view
- We have clicked “New” button in the command bar
- And we have populated a few fields
The interesting part is clicking that “New” button, since that’s when a completely new screen was displayed in CRM. So how did EasyRepro knew NOT to try setting a value for “name” field before that new form was loaded?
This is because EasyRepro was designed with this scenario in mind. If you look at the implementation of SetValue method, you’ll see how one of the calls there is driver.WaitUntilVisible:
Which will, apparently, wait until the element we are trying to set a value for is visible. And the other fail-safe embedded into the EasyRepro framework is that it’ll often wait until the page is fully loaded before returning control to your test code. For example, this is what’s happening right in the end of the ClickCommandButton code – see that call to WaitForPageToLoad?
So, to summarize:
- ThinkTime may be needed if you really want to emulate user behavior. As in, if you want to slowdown the automated test (may be if you don’t want it to turn into a load test, especially if there are plugins/workflows involved. Although, it’s not that a single test session should be able to break Dynamics that way, so.. really there might be no need for this)
- ThinkTime may be needed if you wanted to implement a quick and dirty workaround where there are some events/actions which are not covered by EasyRepro. For example, you may have your own script which is doing ajax processing and which is normally fast, but it’s not fast enough for the automated testing. Although, a better option in that case might be to figure out some other condition, such as to check element visibility, or even to run an additional javascript through the web driver to verify the completion of your ajax call
- Finally, you may need to add some extra ThinkTime if, for whatever reason(maybe you have plugins, maybe you have workflows, etc), Dynamics is not responding fast enough. EasyRepro defines a number of default timeouts in the Constants.cs file, and, if those timeouts are not sufficient for a particular action, your tests may start failing: