Elixir and the Wall of Tests

Here's an experience I tend to have over and over:

  • Generate a new Elixir / Phoenix project
  • Use the super cool Phoenix generators to make a new model
  • Change the model substantially
  • Realize that the tests generated with the model are now super broken

When I get into this situation running mix text produces a huge number of errors. For some reason, I always want to scroll to the top of the error list and work on the first one produced, which makes fixing all of the errors a painful process of save, clear terminal, run command, scroll up, repeat.

Run just one test šŸ§˜

The first thing I do to get some presence of mind and move forward in this situation is stop running the tests. No, not all the tests, though it certainly can be tempting to delete the file and forget about testing. No, just tell the test runner to one a single test at a time.

In ex-unit, Elixir's testing framework which comes built-in to Phoenix, this can be done with what they call "tags".

What are tags?

Test tags are a very flexible feature that allows the programmer to categorize tests throughout the project, and include or exclude whole selections of test based on their tags.

For example?

One example of that comes to mind would be tagging "slow" tests and configuring them only to run before a merge into a repository's main branch.

Back to the topic

Okay, back on topic, here's how we use tags to run just one test at a time. First, find the first test in a broken suite and add this line above its declaration:

@tag :focus
test "does a thing when I do a thing", %{
...

Here I've declared that this test is tagged with the atom "focus". Now, I can run just this test by adding the --only tag to the test command:

mix test --only focus

Now, all of the other tests will be skipped, and only the tagged test will be run. When I've fixed that test, I'll move the tag to the next test in-line. If I've fixed all the tests in a describe block, and I want to verify that they're all working together, I can move that @tag :focus line right above the describe block, and all of the test inside of it will be run. Hurrah!

Keyboard fatigue šŸ„±

Another thing that gets tiresome when working through the wall of tests is command-tabbing to my terminal, up-arrowing, and enter-ing after every file change. mix_test_watch to the rescue! This package will re-run your tests for you after every file change, and it accepts all the same arguments as the normal test command!

Just add it to your mix.exs file:

      ...
      {:phoenix_ecto, "~> 4.1"},      
      # šŸ‘‡ Add this line
      {:mix_test_watch, "~> 1.0", only: :dev, runtime: false},
      ...

And and change test to test.watch in your CLI command:

mix test.watch --only focus

That's a wrap šŸŒÆ

If you're like me, these two steps will help you actually see what's going wrong with the broken tests, instead of just closing your terminal in fear of that massive wall of red text and browsing Twitter until you forget why you were procrastinating in the first place.

 

Murphy

 

2 thoughts on “Elixir and the Wall of Tests

Leave a Reply

Your email address will not be published. Required fields are marked *