When a UI asynchronously updates a value, it can be difficult to make assertions in tests reliably. There are typically two approaches to solving this, either poll the UI until the value matches the assertion (timing out after a certain amount of time) or make the UI notify your test code that a value has changed.
Using the WaitFor class along with Web Driver allows you to do the former with something like this.
Wait for a Condition
1 2 3 4 5 6 | |
This creates an implicit assertion. If the Condition returns true after any number of attempts, the test code continues without incident. If, however, it doesn’t find the value within the timeout, a TimeoutException will be thrown failing your test.
Wait for an Assertion
In tempus-fugit 1.2, there’s a new method on WaitFor to convert the TimeoutException above into a JUnit failure.
1 2 3 | |
Combine it with Conditions.assertion to periodically query the UI and compare it against a Hamcrest Matcher. For example,
1
| |
where, getResultFrom(ui) returns an instance of ProbeFor<T> (a self describing Callable used to query the UI for a T).
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Turn Timeouts into AssertionErrors
Now rather than fail with a TimeoutException, if the assertion hasn’t matched before the timeout expires, a regular JUnit failure (AssertionError) will be thrown. In the IDE, it’ll look something like this.
java.lang.AssertionError: 'number of results' field in the UI
Expected: is "100 matches"
but: <was "">, <was "">, <was "">, <was "">, <was "200 matches">
The describeTo method describes the probe and the Matcher describes what was expected. Because the UI was polled several times, each value was displayed in the ‘but was’ section. On the fifth attempt, a value was found but it didn’t match the expectation.