The event-queue triggering the state change could be overloaded.
I would expect an event-queue to be sequenced; that is, events pushed into the queue in order (1, 2, 3) are popped off the queue in the same order (1, 2, 3 and not 2, 1, 3).
Since the first event should not trigger a change, I would write two tests with the same canvas, each pushing a second event trigger a different change; the test would essentially go:
- Push event X (no change) and event W.
- Assert that nothing changes...
- Until change triggered by W occurs.
You may or may not want a slight pause between X and your Witness event.
The idea of using two tests with different effects is to ensure that you do not accidentally have overlap; that is, that X is not the event causing the effect expected of W.
Even better, though, would be an out-of-band signal.
This is something your development team should be able to provide. For example, you could have a Sequence event with an ID, where upon being processed the ID is reported out-of-bands -- not in-bands to avoid noise/perturbations.
Your tests can then become:
- Send Sequence(0).
- Wait until 0 is reported, signalling the system is started.
- Or timeout, if the start-up takes too long.
- Send Command.
- Send Sequence(1).
- Wait until 1 is reported, signalling the command has been processed.
- Or timeout, if waiting takes too long.
- Check that Command had the expected effect.
Such sequencing can really help test asynchronous systems, and especially reducing the flakiness of tests. It presumes that all asynchronous flows are synchronized, so the synchronization needs to circulate through all sub-systems before being reported.
Ideally, you would start the sequence at a random-number, and then increase it as you go.
If the application supports Heart Beats to monitor its responsiveness in production, then the Heart Beat should contain such a sequence number already to match query/response; ensuring it is well sequenced would then allow its usage for sequencing tests.