Reputation: 5417
Let's say I have an application which must work with two different backends: backend_1 and backend_2. I have two test modules.
Module test_backend_1.py:
@py.test.fixture(scope="session")
def backend_1():
return connect_to_backend_1()
def test_contract_method_1(backend_1):
result = run_contract_method_1()
assert result == backend_1_method_1_get_data()
def test_contract_method_2(backend_1):
result = run_contract_method_2()
assert result == backend_1_method_2_get_data()
and test_backend_2.py:
@py.test.fixture(scope="session")
def backend_2():
return connect_to_backend_2()
def test_contract_method_1(backend_2):
result = run_contract_method_1()
assert result == backend_2_method_1_get_data()
def test_contract_method_2(backend_2):
result = run_contract_method_2()
assert result == backend_2_method_2_get_data()
I want to merge the two modules, and instead provide two different versions of the fixture with the same interface, and run my tests against each one in sequence. Something like this:
@py.test.fixture(scope="session")
def backend():
return [connect_to_backend_1(), connect_to_backend_2()]
def test_contract_method_1(backend):
result = run_contract_method_1()
assert result == backend_method_1_get_data()
def test_contract_method_2(backend):
result = run_contract_method_2()
assert result == backend_method_2_get_data()
Note: I must have N versions (one for each type of backend) of two fixtures: my application and the native backend connector. How do I do it with py.test?
Upvotes: 1
Views: 552
Reputation: 696
I think parametrized fixture is what will work for you very well:
import pytest
@pytest.fixture
def backends():
"""Mapping of possible backend ids to their constructor functions."""
return {
1: connect_to_backend_1,
2: connect_to_backend_2
}
@pytest.fixture(scope="session", params=[1, 2])
def backend(request, backends):
"""Parametrized backend instance."""
return backends[request.param]()
def test_contract_method_1(backend):
result = run_contract_method_1()
assert result == backend.get_data()
def test_contract_method_2(backend):
result = run_contract_method_2()
assert result == backend.get_data()
This is not live yet, but at least you'll get better understanding if you read this fully:
Upvotes: 1
Reputation: 4213
I think, in your case, you can use pytest.mark.parametrize
feature:
def backend1():
return connect_to_backend_1()
def backend2():
return connect_to_backend_2()
def backend3():
return connect_to_backend_3()
..
def backendN():
return connect_to_backend_N()
@pytest.mark.parametrize('backend', [
backend1, backend2, backend3,
..., backendN
])
def test_something(backend):
result = run_contract_method_2()
assert result == backend.method_2_get_data()
Upvotes: 0