elixir

Default ExUnit.Case to use `async: true`


The docs for ExUnit.Case say that the :async option defaults to false and "should be enabled only if tests do not change any global state". In a project I'm working on <1% of our test cases change global state, but people often forget to add async: true to cases that should be async.

Is there a way for a project to instead default :async to true?

The best solution I've come up with so far is to create my own case template that passes my own default into use ExUnit.Case, but I'd like to avoid that if I can. It seems a little weird, and I feel like then people would just forget to use the custom case template. If there was a way to set it in config I'm not finding in the docs, that's more what I'm looking for, I believe.

My preferred workaround as of 2025-07-26: credo has a PassAsyncInTestCases check that, while not defaulting :async to true at least requires test cases to be explicit.


Solution

  • As might be seen in the source code, async attribute goes directly from the options only.

    Maybe the pull request doing somewhat like:

    - async = !!unquote(opts)[:async]
    + async = Keyword.get(
    +   unquote(opts),
    +   :async,
    +   Application.get_env(:ex_unit, :async_all, false)
    + )