Background
For those of you wondering what classical TDD is and Mockist TDD is:
Mainly, classical TDD is focused on testing system boundaries and treats your projects like a black box. It provides for flexible tests that don’t break upon implementation changes.
Mockist TDD, tests the interactions between each component of your app, so it is more coupled to implementation details, but it offers stronger/more precise tests.
TDD in Exlir
I am now trying a new approach to testing apps in Elixir. I have read for the 100th time Mocks and explicit contracts in Elixir and I get the idea of creating interfaces and then having implementations for those. This right here is a classical approach to TDD, if I have ever seen one.
Jose Valim even mentions project boundaries and the need to define those, so I take it that in his mind, all we need to test are the boundaries, which is why we make our applications depend on interfaces (at the boundaries).
This is all fine but…
But I have an issue with this. I know some people love REPL development. I also find it fun - for toy projects. In a real enterprise system, you need a strong suite of tests that can be automatically run. REPL doesn’t cut it.
So, this leaves me with a severe deficiency - how do I test that my system is working internally as expected?
If I only test the boundaries, I have no guarantees.
A very simple example of this is using a cache. If I only test the boundaries, like Jose states, then I will never know if the answer to my query is coming from a cache or from a computation, since to the outside world, both are the same.
It also makes it impossible to test if your processes are being registered correctly, or if your GenServers are doing well instead of just dying, being restarted, and re-running the request with a clean state.
An obvious solution?
Perhaps the obvious solution here would be to just add more boundaries. Boundaries everywhere !
But this is non-sense at best. If we follow this approach we will end up with a contract for every component, because we need to test their interactions. This is crazy.
Questions
- So why is Elixir so focused on classical testing?
- How do you test the interactions within your system?
- If you see yourself as a mockist, which tools to you use? Do you use Mox?