Test driven development in Elixir
For those sleeping in the corner, test driven development is simply having tests run every time you modify a file.
Coming from the rails world, I first looked into something like guard. But guard always felt complicated and bloated. I just want to watch a few files and have my elixir tests be run when they change.
Mix to the rescue
The first discovery was the --stale
mix option,
from it’s documentation:
"Stale"
The — stale command line option attempts to run only those test files which reference modules that have changed since the last time you ran this task with — stale.
The first time this task is run with — stale, all tests are run and a manifest is generated. On subsequent runs, a test file is marked “stale” if any modules it references (and any modules those modules reference, recursively) were modified since the last run with — stale. A test file is also marked “stale” if it has been changed since the last run with — stale.
This means I can just rely on mix for dirty checking and the like. Now to the next part.
Watching files
This might sound silly, but after 20 years, I don’t have a "goto" file watch utility. After a detour to the excellent Elixir slack channel I was pointed to a gist that basically solve my problem.
In one swing, I was introduced to fswatch
which I completely ignored until
now. The --listen-on-stdin
option seems absent from mix, but the workardound
was just to use xargs
.
Long story short, just use the following command:
fswatch -0 --latency=0.01 --one-per-batch lib test web \
| xargs -0 -n 1 mix test --stale test/
We need to add test/
to mix test because xargs
will call mix with an argument
(the number or modified file in this case).
We could remove --one-per-batch
and pass the file directly to mix, but it
would work only for files modified within test/
and not dependecies (lib
and
web
folders).