Responsible - Reactive Asynchronous Testing
Responsible helps you write maintainable high level asynchronous tests in C#:
- Get highly readable and informative output on test failures and timeouts
- Write declarative, composable, and reusable test code
Additionally, in Unity:
- Observe test execution progress while they are running in the Editor
- Stop worrying about a specific long-standing Unity bug
Godot now also has experimental support!
Usage and Output Example
// with 'using static Responsible.Responsibly;'
yield return WaitForCondition("Foo to be ready", () => foo.IsReady)
.AndThen(WaitForCondition("Bar to be completed", () => bar.IsCompleted))
.ThenRespondWith("Foo the bar", Do("Consume bar", () => foo.Consume(bar)))
.ExpectWithinSeconds(10)
.ContinueWith(Do("Continue operation", foo.ContinueOperation))
.ToYieldInstruction(this.TestInstructionExecutor);
If foo.Consume
were to throw an error, the output would look like this:
Test operation execution failed!
Failure context:
[!] Foo the bar CONDITION EXPECTED WITHIN 10.00 s (Failed after 0.12 s ≈ 7 frames)
WAIT FOR
[✓] Foo to be ready (Completed in 0.05 s ≈ 3 frames)
[✓] Bar to be completed (Completed in 0.07 s ≈ 4 frames)
THEN RESPOND WITH
[!] Consume bar (Failed after 0.00 s ≈ 0 frames)
Failed with:
System.Exception:
Something failed
Test operation stack:
[Do] MethodName (at Path/To/Source.cs:39)
[ExpectWithinSeconds] MethodName (at Path/To/Source.cs:40)
[ContinueWith] MethodName (at Path/To/Source.cs:41)
[ToYieldInstruction] MethodName (at Path/To/Source.cs:42)
[ ] Continue operation
Error: System.Exception: Something failed
at <normal exception stack trace comes here>
In Unity, by using the Editor window available under Window -> Responsible -> Operation State
,
you can observe the progress of your tests executing.
The contents of the window updates in real time and matches the output produced on failures,
except for the operation stack and stack trace.
Is That It?
The above sample introduces the responder pattern: an if-then relationship between a wait condition and (optionally) asynchronous response. However, just like it wouldn't be fair to dismiss ReactiveX as just an implementation of the observer pattern, Responsible is also a lot more than just this pattern: the real power of Responsible comes from its composable operators. To read more about the design principles behind Responsible, see the Design Documentation.
BDD-style tests
If you like to write your tests in BDD-style, check out the Responsible.Bdd namespace which forms an embedded DSL to do this with Responsible!
Reactive Programming?
While the design of Responsible was inspired by ReactiveX, it's debatable if Responsible really fits the reactive programming paradigm. While knowing Rx is not necessary for using Responsible, being familiar with reactive and/or functional programming in C# (e.g. LINQ) should ease the learning curve.
Getting Started
- If you are working with Unity, see the Unity documentation.
- If you are working on .NET standard, see the .NET documentation.