Elixir: State of Agents being shared between ExUnit's tests

Created on 7 Dec 2014  路  3Comments  路  Source: elixir-lang/elixir

In a small application built using Agents and Supervisors, the value of an Agent set in a test is visible to another one.

# test/portal_test.exs
defmodule PortalTest do
  use ExUnit.Case

  test "transfer: push data into left struct" do
    Portal.shoot(:orange)
    Portal.shoot(:blue)
    Portal.transfer(:orange, :blue, [1])
    assert [1] == Portal.Door.get(:orange)
    assert [] == Portal.Door.get(:blue)
  end

  test "existent value" do
    assert [1] == Portal.Door.get(:orange)
  end
end

The test suite may pass at first, but fails after some retries. Taking some time, I can narrow the bug better, but decided to report in case is something obvious (for you) or an intended behaviour. For me, it seems that the state is not being cleared in suite's teardown.

How to reproduce

  1. Clone https://github.com/Irio/debug_ex_unit_teardown.
  2. Run mix test multiple times (5 should be enough to see the bug happening).

EDIT: Or maybe it's just because tests are run in parallel and both tests are using the API to connect with the same Agent.

Most helpful comment

Just for the record (I was looking for this xD), this is the updated Mix & OPT link, the one posted by Jos茅 changed.

You have to stop and start the application between tests like this:

setup do
  Application.stop(:your_app)
  :ok = Application.start(:your_app)
end

All 3 comments

ExUnit does not restart your app supervision tree before every test.
If you rely on global state, I'm afraid it's up to you to make sure that you start your tests with a consistent blank slate in your test case setup block.

@xavier exactly. Process are about sharing state and if you don't clean them up between tests, you are going to see failures.

You may wonder though: "why does it fail only sometimes?". That's because we run tests in random order, so sometimes the order causes them to fail, but sometimes it goes ok. Our Mix & OTP guide actually covers how to write a test suite in an application with processes and supervisors.

Just for the record (I was looking for this xD), this is the updated Mix & OPT link, the one posted by Jos茅 changed.

You have to stop and start the application between tests like this:

setup do
  Application.stop(:your_app)
  :ok = Application.start(:your_app)
end
Was this page helpful?
0 / 5 - 0 ratings

Related issues

coryodaniel picture coryodaniel  路  3Comments

sashaafm picture sashaafm  路  3Comments

LucianaMarques picture LucianaMarques  路  3Comments

lukaszsamson picture lukaszsamson  路  3Comments

whitepaperclip picture whitepaperclip  路  3Comments