In a recent project on building a test suite similar to ExUnit in Elixir, I came across the issue of having to track or maintain state for keeping count of the number of assertions passing or failing when a tets suite is run.
I thought this would be the perfect opportunity to try out Agent. From the documentation, an Agent is an abstraction around state and allows different processes to share or store the state.
Since the test assertions are defined using a macro and runs in a separate module and process, using an agent would allow the separation of concerns by allowing the reporting code to reside in a separate module and triggered when needed. The agent can then be started when the actual assertion runs and accumulates a report at the end of the testing process.
The following snippet of code is my implementation of the above:
Within Agent.start_link, we define an initial map with the keys “passes”, “failures” and “totals” to keep track of the various states of the test cases. When a test passes or fails, we call ‘Assertion.Stats.test_pass’ or ‘Assertion.Stats.test_fail’ to update the map appropriately. Then, we call ‘update_test_case_count’ to update the total count for all the test cases run. Finally, we can call ‘report’ to generate a summary of the tests and ‘reset’ simply returns a new map with the values set to 0.
Within the actual macro that defines the assertion, we can invoke the reporter like so:
The actual implementation can be found here