In ExUnit is it possible to mark a single test as non-async?

In ExUnit is it possible to mark a single test as non-async? I know that if you do

  use MyApp.ChannelCase, async: true

All the tests in the file are marked as async (and likewise for false). But if you want to have most tests async except for a few it appears that you are out of luck.

It would be nice to be able to do:

@tag async: false
test "complicated test that uses a genserver or other shared state" do
  # insert test here
end

But that results in cannot set tag :async because it is reserved by ExUnit. So as far as I can tell the available approaches appear to be:

  1. Create separate files for the async vs non-async tests
    a. I don’t favor this because it’s not obvious from looking at one file that the other one exists with different test cases
  2. If a single test in a module has to be non-async then make all the tests in that module non-async

Is there an approach that I’m missing? My use case is that I have a service module that creates an entity in the database and also emits a channel message. So since those channels are potentially shared I need the tests to be non-async.

2 Likes

Define an async module and a sync module in the same file. A single file may help with discoverability.

Possibly name the channels uniquely for each test.

Here’s José’s explanation:

https://elixirforum.com/t/running-async-tests-with-hound/5599/4

2 Likes

Yeah that’s a reasonable work-around. But I’d prefer to keep all the tests for a single method together if possible so you don’t have:

defmodule ExampleSyncTest do
   test "function_a test1"
   test "function_a test2"

   test "function_b test1"

   test "function_c test1"

   test "function_d test1"
   test "function_d test2"
end

defmodule ExampleAsyncTest do
  test "function_b test1"
  test "function_d test1"
end

And then all the setup code can’t be as easily shared either.