Test helpers defined in their own files under the `test` folder not loaded; (and why ElixirLS ignores test_helper.exs contents?)

I’m going through the “Elixir For Programmers” course by Dave Thomas, which uses a simple game as didactic example.

I have written some unit tests for the game, extracted a TestPlayer module with some helper functions, and figured out I could have it loaded by placing it in test_helper.exs (placing it in its own file test_player.ex was like not having written it). Later I discovered that ElixirLS (with VSCode) seemed to ignore the contents of test_helper.exs: jump to definition doesn’t work.

I decided to try to extract the module again in its own file to se if it was going to make ElixirLS happier: test/test_helper/test_player.exs first but file compilation failed, then changed to .ex and still didn’t work.

So I wonder if I can define helper modules in their own files somewhere under the test folder and, ideally, have them loaded both when testing and by ElixirLS?

I can imagine projects where test-helpers would make test_helper.exs very large if that’s the only place where they can be defined, :thinking:

Skimming through three books: Elixir in Action, Programming Elixir 1.6, Testing Elixir; didn’t answer my question.
On Testing Elixir at p.41 I found a test-double defined in integration_tests/soggy_waffle/fake_weather_api.ex; but that integration_tests folder seems non-Mix compliant, it leaves me wondering where they’d actually put it in a project, anyway my .ex file placed under the test folder were ignored.

Check the Elixir LS: Mix Env setting in vscode is set to test. (the default)

I had mine set to dev and when importing the module from a helper file in ./test/support/fixtures/accounts_fixtures.ex the jump to definition was not going to the imported user_fixture() function, but it worked after changing the setting, deleting ./.elixir_ls/ and letting the extension rebuild.

Edit: Sorry, this is my own “XY problem”, probably not relevant to your question if using default settings and @Aetherus’s answer is correct when it comes to non-standard paths.

2 Likes

Check your mix.exs, the project/0 function should look like this:

def project do
  [
    # ...
    elixirc_paths: elixirc_paths(Mix.env()),
    # ...
  ]
end

and in the same file, there should be a private function elixirc_paths/1:

defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
4 Likes

@Aetherus answer did the trick. Thanks anyway for your suggestion, I’ve learned something from it. :slight_smile:

2 Likes

To be fair, the “Testing Elixir” book did have the solution to my question in the paragraph titled “Where to Stick Mock Definitions?”, but I missed it.

Happens to the best of us :sweat_smile:

1 Like