pythonpytestpytest-fixtures

Passing parameters to a pytest fixture that also needs cleanup


I've defined a fixture that accepts arguments to be used in an integration style test that requires some teardown upon completion. It looks something like this:

@pytest.fixture
def create_user_in_third_party():
   from clients import third_party_client

   def _create_user_in_third_party(user: User):
       third_party_client.create_user(user)

   return _create_user_in_third_party

However, we then would like to clean up the created user once the test's lifecycle is complete. In a standard fixture, that may look like:

@pytest.fixture
def create_user():
   user = User(name="Jim")
   user.save()
   yield user
   user.delete()

When applying that same paradigm to the fixture that takes args above, I am not seeing the fixture being called at all (returns a generator that isn't exercising the inner method code).

That code (not working) looks like this:

def create_user_in_third_party():
   from clients import third_party_client

   def _create_user_in_third_party(user: User):
       third_party_client.create_user(user)
       yield # give back control to caller
       third_party_client.delete_user(user)

   return _create_user_in_third_party

is it possible to achieve the above without having to break up creation and deletion into two different fixtures ?


Solution

  • Using the docs that Andrej linked above: https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#factories-as-fixtures , we can use the factory pattern approach to accrue created entities and delete them later. So it ends up looking like this:

    @pytest.fixture
    def create_user_in_third_party():
       from clients import third_party_client
       created_users = []
    
       def _create_user_in_third_party(user: User):
           third_party_client.create_user(user)
           created_users.append(user)
    
       yield _create_user_in_third_party
       for user in created_users:
           third_party_client.delete(user)