title: Using pytest fixtures and peewee transactions together
body: <p>I'm writing a set of unit tests using <code>pytest</code> for some database models that are implemented using <code>peewee</code>. I would like to use database transactions (the database is a Postgres one, if that is relevant) in order to roll back any database changes after each test. </p>
  
  <p>I have a situation where I would like to use two fixtures in a test, but have both fixtures clean up their database models via the <code>rollback</code> method, like so:</p>
  
  <pre><code>@pytest.fixture
  def test_model_a():
      with db.transaction() as txn:  # `db` is my database object
          yield ModelA.create(...)
          txn.rollback()
  
  @pytest.fixture
  def test_model_b():
      with db.transaction() as txn:  # `db` is my database object
          yield ModelB.create(...)
          txn.rollback()
  
  def test_models(test_model_a, test_model_b):
      # ...
  </code></pre>
  
  <p>This works, but reading the <a href="http://peewee.readthedocs.io/en/latest/peewee/transactions.html#explicit-transaction" rel="nofollow noreferrer">documentation for <code>peewee</code></a> suggests that this is error prone:</p>
  
  <blockquote>
    <p>If you attempt to nest transactions with peewee using the <code>transaction()</code> context manager, only the outer-most transaction will be used. However if an exception occurs in a nested block, this can lead to unpredictable behavior, so it is strongly recommended that you use <code>atomic()</code>.</p>
  </blockquote>
  
  <p>However, <code>atomic()</code> does not provide a <code>rollback()</code> method. It seems that when managing transactions explicitly, the key is to use an outer-most <code>transaction()</code>, and use <code>savepoint()</code> context managers within that transaction. But in my test code above, both fixtures are on the same "level", so to speak, and I don't know where to create the transaction, and where to create the savepoint.</p>
  
  <p>My only other idea is to use the order that the fixtures get evaluated to decide where to put the transaction (<a href="https://stackoverflow.com/questions/25660064/in-which-order-are-pytest-fixtures-executed">which seems to be alphabetical</a>), but this seems very brittle indeed.</p>
  
  <p>Is there a way to achieve this? Or does my test design need re-thinking?</p>