Reputation: 9369
I build an application that uses a database in the backend. For integration tests, I start the database in Docker and run a test suite with pytest.
I use a session scoped fixture with autouse=True
to start the Docker container:
@pytest.fixture(scope='session', autouse=True)
def run_database():
# setup code skipped ...
# start container with docker-py
container.start()
# yield container to run tests
yield container
# stop container afterwards
container.stop()
I pass the database connection to the test functions with another session scoped fixture:
@pytest.fixture(scope='session')
def connection():
return Connection(...)
Now I can run a test function:
def test_something(connection):
result = connection.run(...)
assert result == 'abc'
However, I would like to run my test functions against multiple different versions of the database.
I could run multiple Docker containers in the run_database()
fixture. How can I parametrize my test functions so that they run for two different connection()
fixtures?
Upvotes: 3
Views: 1516
Reputation: 9369
The answer by @Guy works!
I found another solution for the problem. It is possible to parametrize a fixture. Every test function that uses the fixture will run multiple times: https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures
Thus, I parametrized the connection()
function:
@pytest.fixture(scope='session', params=['url_1', 'url_2'])
def connection(request):
yield Connection(url=request.param)
Now every test function that uses the connection
fixture runs twice. The advantage is that you do not have to change/adapt/mark the existing test functions.
Upvotes: 1
Reputation: 50819
You can send a function that yields connections and pass it with @pytest.mark.parametrize
. If you change the the scope of run_database()
to class
it will run for every test
def data_provider():
connections = [Connection(1), Connection(2), Connection(3)]
for connection in connections:
yield connection
@pytest.fixture(scope='class', autouse=True)
def run_database():
container.start()
yield container
container.stop()
@pytest.mark.parametrize('connection', data_provider())
@pytest.mark.testing
def test_something(connection):
result = connection.run()
assert result == 'abc'
If you add @pytest.mark.parametrize('connection', data_provider())
to run_database()
the connection will be passed to there as well.
Upvotes: 0