title: where ecto's unit test inserted data?
body: <p>I have imitated hexpm project to write repo related unit test.</p>
  <p>But the duplicated <code>insert</code> operation is always successful and <code>assert :error</code> failed.</p>
  <p>assert error message is as follows:</p>
  <pre><code>macbook:pen yuchen$ mix test
     
   ...
      
        1) test username and email are unique (Pen.Account.UserTest)
           test/pen/accounts/user_test.exs:39
           match (=) failed
           code:  assert {:error, changeset} =
                    User.build(%{
                      name: &quot;some_other_username&quot;,
                      email: &quot;some_other_email@example.com&quot;,
                      password: &quot;password&quot;
                    })
                    |&gt; insert()
           left:  {:error, changeset}
           right: {
                    :ok,
                    %Pen.Accounts.User{__meta__: #Ecto.Schema.Metadata&lt;:loaded, &quot;users&quot;&gt;, email: &quot;some_other_email@example.com&quot;, id: 170, inserted_at: ~U[2022-09-06 08:08:35.902874Z], name: &quot;some_other_username&quot;, password: &quot;$2b$12$M1S.X2GmnGD/uASom2v01OYwdihE7sVbp4YY5mZAwgY9ITPMYdgzu&quot;, updated_at: ~U[2022-09-06 08:08:35.902874Z]}
                  }
           stacktrace:
             test/pen/accounts/user_test.exs:54: (test)
      
      .
      
      Finished in 1.9 seconds (1.7s async, 0.1s sync)
      5 tests, 1 failure
  </code></pre>
  <p>My unit test code is as follows:</p>
  <pre class="lang-elixir prettyprint-override"><code>defmodule Pen.Account.UserTest do
    use Pen.DataCase, async: true
    require Logger
  
    alias Pen.Accounts.{Auth, User}
  
    setup do
      {:ok,user} = insert(%User{password: Auth.gen_password(&quot;password&quot;)})
      %{user: user, password: &quot;password&quot;}
    end
  
    describe &quot;build/2&quot; do
      test &quot;builds user&quot; do
        changeset =
          User.build(%{
            name: &quot;username&quot;,
            email: &quot;mail@example.com&quot;,
            password: &quot;password&quot;
          })
  
        assert changeset.valid?
      end
    end
  
    # test &quot;validates username&quot; do
    #   changeset = User.build(%{name: &quot;x&quot;})
    #   assert errors_on(changeset)[:name] == [&quot;should be at least 3 character(s)&quot;]
  
    #   changeset = User.build(%{name: &quot;{€%}&quot;})
    #   assert errors_on(changeset)[:name] == [&quot;has invalid format&quot;]
    # end
  
    # test &quot;validates password&quot; do
    #   changeset = User.build(%{password: &quot;x&quot;})
    #   assert errors_on(changeset)[:password] == [&quot;should be at least 7 character(s)&quot;]
    # end
  
    test &quot;username and email are unique&quot;, %{user: user} do
      assert {:ok, changeset} =
               (User.build(
                 %{
                   name: user.name,
                   email: &quot;some_other_email@example.com&quot;,
                   password: &quot;password&quot;
                 }
                #  ,
                #  true
               )
               |&gt; insert())
      Logger.debug(&quot;first: #{inspect changeset}&quot;)
      # assert errors_on(changeset)[:name] == [&quot;has already been taken&quot;]
  
      assert {:error, changeset} =
               (User.build(
                 %{
                   name: &quot;some_other_username&quot;,
                   email: &quot;some_other_email@example.com&quot;,
                   password: &quot;password&quot;
                 }
               )
               |&gt; insert())
  
      assert errors_on(changeset)[:email] == &quot;already in use&quot;
      # end
    end
  </code></pre>
  <p>sandbox is used, datacase code is as follows:</p>
  <pre class="lang-elixir prettyprint-override"><code>defmodule Pen.DataCase do
    @moduledoc &quot;&quot;&quot;
    This module defines the setup for tests requiring
    access to the application's data layer.
  
    You may define functions here to be used as helpers in
    your tests.
  
    Finally, if the test case interacts with the database,
    we enable the SQL sandbox, so changes done to the database
    are reverted at the end of every test. If you are using
    PostgreSQL, you can even run database tests asynchronously
    by setting `use Pen.DataCase, async: true`, although
    this option is not recommended for other databases.
    &quot;&quot;&quot;
  
    use ExUnit.CaseTemplate
  
    using do
      quote do
        # alias Pen.Repo
        import Pen.Repo
  
        import Ecto
        import Ecto.Changeset
        import Ecto.Query
        import Pen.DataCase
      end
    end
  
    setup tags do
      Pen.DataCase.setup_sandbox(tags)
      :ok
    end
  
    @doc &quot;&quot;&quot;
    Sets up the sandbox based on the test tags.
    &quot;&quot;&quot;
    def setup_sandbox(tags) do
      pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Pen.Repo, shared: not tags[:async])
      on_exit(fn -&gt; Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
    end
  
    @doc &quot;&quot;&quot;
    A helper that transforms changeset errors into a map of messages.
  
        assert {:error, changeset} = Accounts.create_user(%{password: &quot;short&quot;})
        assert &quot;password is too short&quot; in errors_on(changeset).password
        assert %{password: [&quot;password is too short&quot;]} = errors_on(changeset)
  
    &quot;&quot;&quot;
    def errors_on(changeset) do
      Ecto.Changeset.traverse_errors(changeset, fn {message, opts} -&gt;
        Regex.replace(~r&quot;%{(\w+)}&quot;, message, fn _, key -&gt;
          opts |&gt; Keyword.get(String.to_existing_atom(key), key) |&gt; to_string()
        end)
      end)
    end
  end
  </code></pre>
  <p>I have checked postgres db，the users table records are not increased after every unit test.</p>
  <pre><code> id | name |            email             |                           password                           |     inserted_at     |     updated_at      
  ----+------+------------------------------+--------------------------------------------------------------+---------------------+---------------------
    1 |      |                              | $2b$12$hw0fBhi7PtcjVdXRocxnReaToBe.IyeFZa7qvRolU2ymdgcmFbufW | 2022-09-06 05:47:41 | 2022-09-06 05:47:41
  </code></pre>
  <p>users's migration is as follows:</p>
  <pre class="lang-elixir prettyprint-override"><code>defmodule Pen.Repo.Migrations.CreateUsers do
    use Ecto.Migration
  
    def change do
      create table(:users) do
        add :name, :string
        add :email, :string
        add :password, :string
  
        timestamps()
  
      end
      create unique_index(:users, [:name],[unique: true])
      create unique_index(:users, [:email],[unique: true])
    end
  end
  </code></pre>
  <p>postgres users's structure is as follows:</p>
  <pre><code>                                          Table &quot;public.users&quot;
     Column    |              Type              | Collation | Nullable |              Default              
  -------------+--------------------------------+-----------+----------+-----------------------------------
   id          | bigint                         |           | not null | nextval('users_id_seq'::regclass)
   name        | character varying(255)         |           |          | 
   email       | character varying(255)         |           |          | 
   password    | character varying(255)         |           |          | 
   inserted_at | timestamp(0) without time zone |           | not null | 
   updated_at  | timestamp(0) without time zone |           | not null | 
  Indexes:
      &quot;users_pkey&quot; PRIMARY KEY, btree (id)
      &quot;users_email_index&quot; UNIQUE, btree (email)
      &quot;users_name_index&quot; UNIQUE, btree (name)
  </code></pre>