Reasonable defaults can make your life easier. I think that most programmers agree with that. Does that mean we should stick to them forever? Can a particular solution be suitable for everything and everyone?
This article tells the story of my experiment, which proved that sometimes it is worth breaking well-established standards.
Let's start with the standard elixir project.
.
├── config
│   └── config.exs
├── lib
│   ├── foo
│   │   ├── bar.ex
│   │   └── baz.ex
│   └── foo.ex
├── mix.exs
└── test
    ├── foo
    │   ├── bar_test.exs
    │   └── baz_test.exs
    ├── foo_test.exs
    └── test_helper.exs
It's the output of mix new foo with two additional modules: Foo.Bar and Foo.Baz added manually. You can imagine this is your favorite small open-source library.
In my opinion, it has the following advantages:
lib out of boxlib is added to the package, the content of test isn't)I don't like having separate lib and test folders in phoenix projects. Ones that are big and not meant to be pushed to hex.
I'm bad at remembering shortcuts and names. On the other hand, I'm pretty good at remembering where individual files are stored (especially when the project has a clear division into small contexts). However, I don't want to go through the second tree with the same structure to get to the tests. It has always been a bit annoying.
One day while reading the documentation of mix test task, I found out the following options: :test_paths and :test_pattern. The mere fact that such options exist in Elixir codebase means that they were useful to someone. I decided to check if they would also be useful for me.
First, I changed :test_paths value to ["lib"]. It allowed me to keep a file with tests next to the file with implementation. It also forced me to move .test_helper.exs to the root of lib, but one additional file isn't a problem. What bothered me more was the alphabetical order. Of two files with the same prefix, the one ending with _test.exs was higher than its .ex counterpart. It made the files tree in my editor look weird. Luckily, it was easy to fix by changing :test_pattern value to "*.test.exs". From now on, files with tests had to be named like this: my_module.test.exs.
.
├── config
│   └── config.exs
├── lib
│   ├── foo
│   │   ├── bar.ex
│   │   ├── bar.test.exs
│   │   ├── baz.ex
│   │   └── baz.test.exs
│   ├── foo.ex
│   ├── foo.test.exs
│   └── test_helper.exs
└── mix.exs
I was pleased with what I was able to achieve.
No.
After a few weeks of work in this way, new advantages appeared:
.test.exs file associated with it.It also has some disadvantages:
:test_paths and :test_pattern for every new umbrella application.test folder.However, these are minor ones comparing to how more comfortable my work has become.
I'm aware this topic may be controversial for some people. I encourage you to leave me a comment if you think that I've missed something.
Did you find the article interesting and helpful? Take a look at our Elixir page to find out more!