Sin of Using Thread.sleep() in Selenium Scripts for Waits

Wait problem is probably the most common errors in Selenium scripts especially for Javascript rich web applications. How long a Selenium script should wait before interacting with web elements?
  • 2s / 5s / 15s / 1min?
  • Until interested page is loaded?
  • Until all images of a page are downloaded?
  • Until all AJAX requests have been completed?
  • Until all manipulation of DOM elements is complete?

It has been observed that people frequently wait for a fixed duration in their Selenium script using Thread.sleep() function before interacting with a web element. It is a worst kind of wait that can be used in a script. Then, why people use it? One reason could be ignorance but mostly it could be due to carelessness or unavailability of time to complete a quality (stable) script. What are some ways to discourage team members to not use Thread.sleep() or similar method in the code?
  1. Having strict review process, where compiler itself can flag warnings on finding Thread.sleep() or wait() in the test code
  2. Implementation of custom wait method in the automation framework, which can be used by the project team members

What are some better ways to wait in Selenium scripts than Thread.sleep()?
The key for answering this question is to know when a web element is ready for interactions. It is really complex and depends on the context or pre-conditions. Few web elements could be available just after the page load whereas few others could only be available when all AJAX requests are processed and DOM is ready for use. There could be some scenarios, where a web element is enabled or visible only after changing the state of another web element. So, we should incorporate wait methods, having capability to wait flexibly depending on multiple pre-conditions.
There are three built-in waiting mechanisms Selenium supports, which can be configured while instantiating a webdriver object using timeout properties.
  1. Page load timeout - the amount of time Selenium will wait for a page to load.
  2. Script timeout - the amount of time Selenium will wait for a bit of Javascript to execute
  3. Implicit wait timeout - Selenium will wait up to configured timeout for an element to appear in the DOM when trying to find it.

Note: In Thread.sleep(), Selenium has to wait mandatorily for the specified timeout whereas in the Implicit wait, Selenium can stop waiting if element is found before configured timeout value.
Though the recommended mechanism of waiting is ‘Explicit Wait’, which is a kind of wait for certain conditions to occur before proceeding further. It is implemented using WebDriverWait, FluentWait & ExpectedConditions class.

By now, we have better understanding of wait mechanisms to use in Selenium scripts but still one last question is left for beginners to understand - Why Thread.sleep() shouldn’t be used in Selenium scripts for waits?

Well, it is expected from any automation engineer to design scripts, which are reliable. No one in team, need scripts which works intermittently. Time taken for debugging a false positive / negative is enormous and demotivate automation initiatives in the project. There could be different reasons for scripts to fail intermittently but it mustn’t be because of Thread.sleep() being used in the code. Enough has been discussed already by many on this topic and any excuse on this shouldn’t be entertained. Your tests may slow down if your wait time is more and may fail if it is less.
If your reason is that I know what should be the exact time for my waiting. In that case, consider below external factors also while taking this decision -
  1. Javascript engine performance varies with web browsers being used. It impacts the web element rendering time for JavaScript heavy web applications
  2. Performance of machine, being used for test execution. Are tests run from server class machine, desktop class machine, virtual machines, dockers etc?
  3. Network used for connecting the web server applications. Are tests being run on VPN, LAN, WAN, Wireless, mobile bandwidth etc?
  4. Performance of machine, being used for web application deployment? Is server deployed on virtual machine, data center, cloud etc.?
  5. Application environment being used for test execution. Are tests being executed on developer machine, pre production environment or production environment?
  6. Usage of application during testing. Is application being heavily used by other users while tests are running or tests are being run in isolation?

So, avoid Thread.sleep() at all in the Selenium scripts. Give time for refactoring. The recommended mechanism of waiting is ‘Explicit Wait’, which is a kind of wait for certain conditions to occur before proceeding further.


Comments

Popular posts from this blog

Performance Test Run Report Template

Understanding Blockchain

Bugs Management in Agile Project