Strategies for testing reactive, asynchronous code
- by Arne
I am developing a data-flow oriented domain-specific language. To simplify, let's just look at Operations. Operations have a number of named parameters and can be asked to compute their result using their current state.
To decide when an Operation should produce a result, it gets a Decision that is sensitive to which parameter got a value from who. When this Decision decides that it is fulfilled, it emits a Signal using an Observer.
An Accessor listens for this Signal and in turn calls the Result method of the Operation in order to multiplex it to the parameters of other Operations.
So far, so good, nicely decoupled design, composable and reusable and, depending on the specific Observer used, as asynchronous as you want it to be.
Now here's my problem: I would love to start coding actual Tests against this design. But with an asynchronous Observer...
how should I know that the whole signal-and-parameters-plumbing worked?
Do I need to use time outs while waiting for a Signal in order to say that it was emitted successfully or not?
How can I be, formally, sure that the Signal will not be emitted if I just wait a little longer (halting problem? ;-))
And, how can I be sure that the Signal was emitted because it was me who set a parameter, and not another Operation? It might well be that my test comes to early and sees a Signal that was emitted way before my setting a parameter caused a Decision to emit it.
Currently, I guess the trivial cases are easy to test, but as soon as I want to test complex many-to-many - situations between operations I must resort to hoping that the design Just Works (tm)...