In a previous post a described an event driven domain design to run a resuscitation protocol. I also mentioned that running this protocol in practice can have some pitfalls. One of these pitfalls is the use of a defibrillator that is required to apply a cardio conversion by delivering a shock. We have to test that this cannot ever occur.
First to deliver the shock, the defibrillator has to be charged. However, during the whole procedure it is essential to perform cardio pulmonary resuscitation (CPR, i.e. performing chest compressions along with ventilation breaths) without the least amount of interruption. The sequence looks like follows:
- Charge the defibrillator while CPR is continuing
- When charged perform a rhythm check
- If the rhythm requires cardio-version, apply the shock
- If the rhythm does not require cardio-version do not shock
- Immediately commence with CPR
- If no shock was delivered, discharge the defibrillator
So, it is important to do the rhythm check with the defibrillator charged and either perform cardio-version or discharge the defibrillator.
Both charging the defibrillator and forgetting to discharge the defibrillator are easily forgotten. Also note that the following sequences should NOT occur:
- Charge when already charged
- No cardio-version but no subsequent discharging
- Shock and when no previous charge
- Discharge when no previous charge
So, a lot can go wrong. And each of the above list can be viewed as a property of the events that have occurred. Using property based testing this can be quite nicely achieved.
First, we need some functions that randomly runs the resuscitation protocol to create random scenarios, i.e. random lists of events that occurred as a result of following the protocol.
These helper functions create a random protocol run until an ending event, either signs of life or return of spontaneous circulation.
The property test uses the generated events to check the sequence of charge -> shock or charge -> discharge events.
The property test uses the FsCheck library to test the property. FsCheck library will generate random numbers n that in turn is used as a seed number in the runRandom function.
- line 09 checks: Charge when already charged
- line 28 checks: No cardio-version but no subsequent discharging
- line 19 checks: Shock when no previous charge
- line 20 checks: Discharge when no previous charge
FsCheck will try to find the minimal failing test. So, when it fails it will report for example that the test failed at n = 3.
You can then check the exact sequence of events by running:
The result is that the property is tested without having to specify specific scenarios, as there can always be one more scenario that you forgot to test.
And just to be sure:
This will check 365 unique scenario’s.