The Missing Bit

Test driven development in Elixir
January 29, 2017

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).