Testing side effects Elixir

Background

I have a module that uses eralngs persistent_term. I have some tests that try to use this module and a test file that looks like the following:

defmodule MyAppTest do
  use ExUnit.Case

  describe "group 1" do
    
    setup do
      :persistent_term.put("hello", :world)
      :ok
    end

    test "test 1" do
      assert MyApp.run(:random_data)
    end

  end

# describe group2 ....

end

Problem

Here the code in the setup block will run before each test inside the describe block. However, since persistent_term is a side effect, this will leak to other tests. MyApp.run/1 uses :persistent_term, so it means that MyApp.run/1 has side effects.

Question

How do you test functions with side effects in Elixir?
How would you test MyApp.run/1 without leaking the test data into other tests?

use ExUnit.case, async: false

This is probably the only answer for this…

But anyway, you are not testing the sideeffect, but you are testing your function under a certain environment. Slightly different…

Anyway, I still think that running them with async: false and properly cleaning up is your only option…

Are you testing configuration instead of some code?

It tests behaviour under a certain configuration if you want to say so…

And yes, sometimes I do so…

Anyway, under “testing sideeffects” I’d actually understand, to test if a file exists and has a given content after calling File.write.

iirc, async: false does not mean my tests will run synchronously between each other, it means that each test file will run 1 at a time, instead of running all test files at the same time.

So it is unclear to me how this would be a solution to the issue at hand.

Am I incorrect?

I’m testing code. The module at hand has functions that save data to :persistent_term. I want to make sure that data is being saved correctly.

:wave:

Tests within a single test file always run after one another, never at the same time. You can update your setup block to clean the persistent term storage and then insert “hello”. This way all test block would start with known state.

1 Like