6

Is it possible in elixir to have my test modules in the same directory as the modules they are testing?

A typical Elixir project has a structure like this:

project
|-- lib
|   `-- my_module.ex
`-- test
    |-- my_module_test.exs
    `-- test_helper.exs

When writing node projects I like to have my test modules next to the modules they are testing. This is easily configarable using tools like Jest:

project
|-- lib
|   |-- my_module.ex
|   `-- my_module.test.exs
`-- test
    `-- test_helper.exs

Is it possible to have a similar setup in Elixir/Exunit?

mit
  • 11,083
  • 11
  • 50
  • 74
harryg
  • 23,311
  • 45
  • 125
  • 198
  • 1
    Yes, this is possible. Elixir compiler does not care about where your files are located in the directory tree. Literally, you might put everything in the root folder. – Aleksei Matiushkin Jul 26 '18 at 14:37
  • Indeed, my question was really about the *how* as by default Exunit looks in the `test` directory for tests? – harryg Jul 26 '18 at 14:38
  • It turned out I was wrong. [Invoking `mix test` from the command line will run the tests in each file matching the pattern `*_test.exs` found in the **`test`** directory of your project](https://hexdocs.pm/ex_unit/ExUnit.html#module-integration-with-mix). – Aleksei Matiushkin Jul 26 '18 at 14:44
  • So I guess the test pattern is not configurable. That is a shame – harryg Jul 26 '18 at 14:47
  • 1
    It depends on what approach is taken. I prefer to use standards rather than to invent my own squared wheels. After all, [I believe] nobody in Elixir community wants to meet a project that has tests mixed with code. – Aleksei Matiushkin Jul 26 '18 at 14:52
  • That's fair enough - although in node it's quite common to have your tests next to code. But agree that sticking to standard is better. As an aside I found this which suggests it might be configurable: https://github.com/elixir-lang/elixir/blob/165048513d84473a628220bb533dc726d98ac314/lib/mix/lib/mix/tasks/test.ex#L367-L373 – harryg Jul 26 '18 at 14:59
  • Good catch! Then if you insist on doing node in elixir just put `test_paths: "."` into `project` callback of your `mix.exs`. – Aleksei Matiushkin Jul 26 '18 at 15:06

1 Answers1

9

OK, I’ll put it as an answer for the sake of future visitors.

Mix documentation explicitly states

Invoking mix test from the command line will run the tests in each file matching the pattern *_test.exs found in the test directory of your project.

It looks like ExUnit authors strongly discourage developers to put tests somewhere else. As @harryg discovered, it’s still possible, though. project settings have tests_path variable that is checked for where tests are to be found (and test_pattern for the pattern,) defaulted to "test" and "*_test.exs" respectively.

To reset it to some other value, simply update the project callback adding these two lines:

  def project do
    [
      app: @app,
      version: @version,
      elixir: "~> 1.6",
      start_permanent: Mix.env() == :prod,
      ...
      test_paths: ".",
      test_pattern: "*_test.exs" # or something else
    ]
  end
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160