Writing Elixir tests for greater long-term value: tricks and tools
Short summary: There are "tricks of the trade" for writing readable, maintainable tests that help produce a more coherent system. This talk shows some of them, with an emphasis on code you can use or copy today.
Longer description:
Two common principles for writing good tests are:
-
Make them scannable. Scannable tests make it easy to quickly see what a module is for (if you're trying to understand it) and can better remind you of special design cases (if you're going to change it).
-
Make them focused by avoiding any words not relevant to the purpose of the test. Focused tests are usually more maintainable. But, more importantly, they can help programmers think about the problem to be solved and the design that solves it.
In the talk, I won't argue for those principles at any length. Rather, I'll show them in action by converting some typical Phoenix tests into scannable, focused tests. I'll speak about some subset of these topics:
- pipelining assertions
- using a broader set of general purpose assertions tailored to, for example, map structures and changesets
- domain-specific languages for setup
- tabular formatting
- separating out special cases into a "cabinet of curiosities" that showcases exemplary data
- the importance of team style and habits
- the use of Boyd Multerer's PhoenixIntegration library to simplify unit tests
I highlighted PhoenixIntegration
above because my goal is not just to show principles in action but to provide pointers to code ready for use or copying.
You can see examples of such tests at https://github.com/marick/crit19/tree/master/test/crit_biz/view_models/setup. (Note: I'm currently revising that code as part of separating my use of Ecto from its out-of-the-box style to a style using something like View Models. I'm also actively fiddling with the tests to make them into better examples.)