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.