Testing efficiently

Hi *.
My question today is about testing with ExUnit, I believe that I’m missing something about testing but also with how I’m designing my Elixir app.
The main “problem” is that I mainly use private functions: for some reason it appears natural to me to have an entry point in a module, and develop all the functionalities as private functions that I pipe together, pretty much as in the Github example on Dave Thomas book.
Using this approach, I can only write very high level black box testing, because most of my functions are private and can’t be tested using ExUnit. I also find quite difficult to take my test suite as reliable, code coverage is quite low even for a newbie like me.
I’ve tried to look at some bigger projects but they appear to be a little out of my league at the moment.
Am I doing something wrong? Does anybody else feel the same? Every suggestion is very welcome.

2 Likes

I’ve always considered that it would be useful to have a compiler flag (to be set during a test build for example) that makes defp act like def, to expose everything. You could make a macro to do it yourself though but would have to import it everywhere you want to test.

2 Likes

Hi @ngw,

Welcome to Elixir !

In my opinion, your approach is good. It is fine to develop a module with a public api and a private api. Unit tests will test the private api of your module by testing its public api. There is nothing wrong with that.

However, it is also fine to listen to your gut feeling. If you believe that you should test more thoroughly the private api of your module, perhaps it is because the private api is doing too much. Have you considered extracting (part of) the private api to its own module ? This is a magic trick to transform private functions into public ones. It also allows you to test them. If you feel this is not the right approach, then perhaps your gut feelings are telling you that you haven’t written enough tests for the public api of your module.

So to summarize, you have 3 options:

  • have faith in your unit tests: when they test the public api of your module they also test the private api
  • write more tests for your public api, have you covered all scenarios ?
  • extract your private api to its own module, most functions should become public and testable

Good luck

7 Likes

Thank you very much for the advice, I’ve extracted some more code and made new modules and I’m more confident about my test suite.
Probably my gut feelings come from the fact I’m used to Ruby and other OOPL where everything is very different, probably with time I will be more confident.

ngw