In order to test how my database behaves when I add two very similar data rows, I need to setup a new database for each combination of parameters. I'm also using Hypothesis' strategies to generate "similar" data rows.
The test work flow should go as:
for example in hypothesis-given-examples: # @given
for combination in pytest-parametrized-combinations: # @pytest.mark.parametrize
db = setup_db(example, combination) # should be a fixture with `yield` but I can't parametrize it
do_test_1(db) # using the setup database
do_test_2(db) # using the setup database
do_test_3(db) # using the setup database
teardown(db)
I started with:
@mark.parametrize('different_properties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
@mark.parametrize('different_identproperties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
@mark.parametrize('different_labels', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
class TestMerge:
@classmethod
@given(node1=node_strategy, sampler=data())
def setup_class(cls, node1, sampler, different_labels, different_properties, different_identproperties):
node2 = create_node_from_node(node1, sampler, different_labels, different_properties,
different_identproperties) # uses hypothesis to generate
cls.node1, cls.node2 = node1, node2
def test_merge(self):
read_node1, read_node2 = read(1), read(2)
# do some test here comparing input and output
But it seems that is impossible to do a setup like this
So I tried to use a fixture with an indirect argument, but I want to do this for a whole class and copying the parameters for each test method seems ridiculous and also I can't make a cartesian product of parameter lists using indirect arguments that feed to one fixture.
Here is a minimal running/erroring example:
import pytest
from hypothesis import strategies as st
from hypothesis import given
@pytest.mark.parametrize('different_properties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'], scope='class')
@pytest.mark.parametrize('different_identproperties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'], scope='class')
@pytest.mark.parametrize('different_labels', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'], scope='class')
class TestMerge:
@classmethod
@given(node1=st.integers(), sampler=st.data())
def setup_class(cls, node1, sampler, different_labels, different_properties, different_identproperties):
node2 = node1 * 2 # just for the minimal example
cls.node1, cls.node2 = node1, node2
def test_merge(self, different_labels, different_properties, different_identproperties):
# read_node1, read_node2 = read(1), read(2)
# do some test here comparing input and output
pass
Pytest output:
ERROR test_minimal_example.py::TestMerge::test_merge[False-False-False] - TypeError: setup_class() missing 3 required...
ERROR test_minimal_example.py::TestMerge::test_merge[False-False-entirekeys] - TypeError: setup_class() missing 3 req...
...
Hopefully you can see what I'm trying to do. If not, please ask!
Thanks!