What are the recommended approaches to using Thread.sleep()
to speed up tests.
I am testing a network library with a retry functionality when connections are dropped or timeout errors occur, etc. The library however, uses a Thread.sleep()
between the retries (so it won't connect thousands times while the server is restarting). The call is slowing the unit tests significantly, and I wonder what the options are to override it.
Note, I'm open to actually changing the code, or using a mocking framework to mock Thread.sleep(), but would like to hear your opinions/recommendation first.
Using Thread. sleep() frequently in an automation framework is not a good practice. If the applied sleep is of 5 secs and the web element is displayed in 2 secs only, the extra 3 secs will increase the execution time.
sleep() in Selenium Java because it is a static wait. Selenium WebDriver will have no choice but to wait for the specified time, regardless of the fact that the element has been located or not. This is why we prefer not to use Thread. sleep() multiple times in our automation scripts.
sleep() functions to execute, it always pauses the current thread execution. If any other thread interrupts when the thread is sleeping, then InterruptedException will be thrown.
It is usually a good idea to delegate time-related functionality to a separate component. That include getting the current time, as well as delays like Thread.sleep(). This way it is easy to substitute this component with mock during testing, as well as switch to a different implementation.
I just faced a similar issue and I created a Sleeper
interface to abstract this away:
public interface Sleeper
{
void sleep( long millis ) throws InterruptedException;
}
The default implementation uses Thread.sleep()
:
public class ThreadSleeper implements Sleeper
{
@Override
public void sleep( long millis ) throws InterruptedException
{
Thread.sleep( millis );
}
}
In my unit tests, I inject a FixedDateTimeAdvanceSleeper
:
public class FixedDateTimeAdvanceSleeper implements Sleeper
{
@Override
public void sleep( long millis ) throws InterruptedException
{
DateTimeUtils.setCurrentMillisFixed( DateTime.now().getMillis() + millis );
}
}
This allows me to query the time in a unit test:
assertThat( new DateTime( DateTimeUtils.currentTimeMillis() ) ).isEqualTo( new DateTime( "2014-03-27T00:00:30" ) );
Note that you need to fix the time first using DateTimeUtils.setCurrentMillisFixed( new DateTime( "2014-03-26T09:37:13" ).getMillis() );
at the start of your test and restore the time again after the test using DateTimeUtils.setCurrentMillisSystem();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With