0

If 2nd test case runs after 1st test case then it is getting failed as the database is having ReservationInfo Entry which got created in the 1st test case.

defmodule MyProj.TestABC do
    use ExUnit.Case
    alias MyProj.Models.ReservationInfo
    alias MyProj.Repo

    test "Create Coordinates" do
        reservation_result = ReservationInfo.create(["00.00", "00.01"])          
        assert reservation_result == [{"00.00", :created}, {"00.01", :created}]
    end

    test "Shouldn't have above created coordinates as it's different test case" do
        assert [] == ReservationInfo.get_all()
    end
end

I would like to truncate all data before running new test case, Just like Django cleans data for every test case.

3 Answers 3

2

In your test.exs configs, add a sandbox pool for your repo:

config :your_app, YourApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "yourapp_test",
  username: "username",
  password: "password",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox

In your test file have a setup block:

setup do
  :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo)
end

Then, when you run the tests, use the MIX_ENV=test environment:

MIX_ENV=test mix test
1

Since you're using Phoenix, there's a nifty helper to manage this for you in test/support/data_case.ex.

The assumption is that this helper is used in tests that need access to the data layer, so it runs each individual test block in its own database transaction, rolling back the transaction when the test completes.

Simply replace ExUnit.Case with TestABC.DataCase and you should be good to go. Note: you generally don't want to use :async mode because of side-effect potential and deadlock potential as test run.

Here's some additional documentation beyond the implementation from the phoenix guides: https://hexdocs.pm/phoenix/testing_schemas.html#test-driving-a-changeset.

2
  • Ah I misunderstood the question to mean cleaning up before the test is run again sorry. Based on the real problem you'd want to use the setup function as described in the top most answer. Although, I'd recommend encapsulating all your tests that need the data created in describe blocks, and all your tests that don't want data in a separate describe block (each describe block uses its own setup process) to speed them up and make development more ergonomic Commented Jul 6, 2018 at 0:44
  • I would use async anyway because: 1) side effects and deadlocks are bugs and running in async exposes them; it is always possible to write queries in such a way that they don't collide with any other queries running in parallel 2) tests run much faster. Who doesn't like faster?!?!
    – pmarreck
    Commented Feb 18, 2021 at 22:59
1

You can use setup to define a callback to be run before each test in a case.

def clean_test_data(context) do
  # perform setup
  :ok
end

setup :clean_test_data
5
  • This was I knew, I thought it should have some better approach.
    – Anurag
    Commented Jul 10, 2018 at 15:00
  • I was having hope that Phoenix as a Framework must be providing auto db truncation on every test case, just like django does.
    – Anurag
    Commented Jul 11, 2018 at 6:49
  • @Anurag, most Phoenix people use Postgres which has transactions; these are used in tests, avoiding having to truncate between every test at all, since every change is just rolled back. Much more intelligent way to do it, and probably faster as well
    – pmarreck
    Commented Feb 18, 2021 at 22:58
  • @pmarreck Testcase's context is changing due to other test cases then it will give unnecessary random failures.
    – Anurag
    Commented Feb 19, 2021 at 5:34
  • @Anurag Those are "bugs". If, for example, you have a test that tests truncation of a table running concurrently with a test adding records to that table, and they're both running inside transactions, then in theory there should never be a failure because all the changes occur at once when the transaction is committed and only then do the changes become "visible" to other processes.
    – pmarreck
    Commented Feb 19, 2021 at 23:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.