MichaelJones
MichaelJones

Reputation: 1406

How do I avoid ExUnit.start() error when running mix test

When I run mix test on my project, I get the following error and I don't understand why:

$ mix test
Compiling 2 files (.ex)

== Compilation error in file lib/myproject_web/controllers/email_controller_test.ex ==
** (RuntimeError) cannot use ExUnit.Case without starting the ExUnit application, please call ExUnit.start() or explicitly start the :ex_unit app
    expanding macro: ExUnit.Case.__using__/1
    lib/myproject_web/controllers/email_controller_test.ex:2: MyProjectWeb.EmailControllerTest (module)
    (elixir 1.10.1) expanding macro: Kernel.use/2
    lib/myproject_web/controllers/email_controller_test.ex:2: MyProjectWeb.EmailControllerTest (module)

I already have a test_helper.exs file in lib/ which calls ExUnit.start(). My set up is unusual because I want the tests next to the modules rather than in a separate test folder.

Upvotes: 2

Views: 1501

Answers (2)

Daniel
Daniel

Reputation: 2554

If you read the documentation of mix test:

This task starts the current application, loads up test/test_helper.exs and then requires all files matching the test/**/*_test.exs pattern in parallel.

You were right that .exs files are not compiled, however this is not a problem if they even were compiled. Tests are run as scripts to avoid repeatedly compilation, since they get randomized order every time, having different output compilation.

The task first compiles all the files, then starts the ExUnit and expands all the macros from *_test.exs scripts. To prove this take a look at this piece of code:

defmacro __using__(opts) do
    unless Process.whereis(ExUnit.Server) do
      raise "cannot use ExUnit.Case without starting the ExUnit application, " <>
              "please call ExUnit.start() or explicitly start the :ex_unit app"
    end

This means that in files where you use use ExUnit.Case, the ExUnit server should be up and running at the moment when these scripts are interpreted.

In general in your case, even after changing to .exs your tests shouldn't have worked, since with default configuration the path for tests is:

 defp default_test_paths do
    if File.dir?("test") do
      ["test"]
    else
      []
    end

Instead you should have called the tests with:

mix test test/some/particular/file_test.exs

Upvotes: 1

MichaelJones
MichaelJones

Reputation: 1406

It turns out this error comes from the test file having a .ex extension rather than .exs. With .ex then mix tries to compile it with everything else before running the tests and then complains because ExUnit.start() hasn't been called at compile time.

With the .exs extension then the file isn't compiled but is run by mix test after the ExUnit.start() has been called from test_helpers.exs.

Upvotes: 2

Related Questions