Best practices for Julia unit testing

I think one of the best practices is to use SafeTestsets.jl

Since otherwise your testsets can leak, i.e. you can have tests which require being run in order, and if you run them on their own they can fail. Safetestsets puts everything in specific modules, so even if you do things like include, the function definitions of one test do not effect another.

Once you have this, you can make every single test script be an independently runnable file, a fully reproducible script for a single idea. Then you can just include the script:

If you do it like this, then every test script can be used independently, which is really nice for development. For example, if this test fails:

you can just pick up this script and start hacking away at it. There’s no dependency on some function or data defined elsewhere (something I particularly dislike when PRing to some older packages which don’t disentangle their tests…)

There are obviously some downsides to this. For example, maybe you want to use the same function in a few places, and this approach would have you define independent versions, which means it would compile each time. However, I think the advantage of having tests that actually run what you think they run far outweighs this.

I cannot even fully describe the number of times I have found tests in unsafe setups which only pass because of a random function definition that in a different test file that nobody knew about, so on CI the test was actually testing nothing while locally if you run the script in isolation you think it’s a good test.

18 Likes