Running code after all ExUnit tests are done

Is there a recommended way of running some code after all ExUnit tests are run? I’m talking about all tests in all modules, not all tests in a certain module.

2 Likes

Ok, to answer my own question: It’s simple but a little counter-intuitive. If you need to run some code after all tests are run you can write a Formatter, which is a GenServer that catches events emitted by the test suite. They are usually used for formatting, but they can run arbitrary elixir code, so it’s good enough for me.

2 Likes

How about test: ["test", "after.test"] as alias in mix.exs?

5 Likes

I’m pretty sure this is a better solution! :slight_smile:

The only issue with test: [“test”, “after.test”] solution is if I specify a file to run the tests, it will run all the test files.

Example:
mix test test/controller/hello_controller_test.exs it will run as mix test.

I’ve tried to find a solution, but the closest I could find was specify on each test module on_exit callback.

1 Like

Faces with the same problem, the reason is that arguments apply to the last task in the list, and I solved it this way:

test: [..., &run_test/1]
...

defp run_test(args) do
  Mix.Task.run("test", args)
  ... # after test
end
3 Likes

An after_suite callback has been added to ExUnit in the meantime. Add this to test_helper.exs:

ExUnit.after_suite(fn _ ->
    # do stuff
end)

9 Likes