如何使用 Hypothesis @given 参数化 pytest 类?

Luc*_*nse 5 python pytest python-hypothesis

为了测试添加两个非常相似的数据行时数据库的行为方式,我需要为每个参数组合设置一个新数据库。我还使用假设的策略来生成“相似”的数据行。

测试工作流程应如下:

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)
Run Code Online (Sandbox Code Playgroud)

我开始于:

@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
Run Code Online (Sandbox Code Playgroud)

但似乎不可能进行这样的设置

因此,我尝试使用带有间接参数的固定装置,但我想对整个类执行此操作,并且复制每个测试方法的参数似乎很荒谬,而且我无法使用提供的间接参数制作参数列表的笛卡尔积到一个固定装置。

这是一个最小的运行/错误示例:

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
Run Code Online (Sandbox Code Playgroud)

pytest 输出:

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...
    ...
Run Code Online (Sandbox Code Playgroud)

希望你能看到我正在努力做的事情。如果没有,请询​​问!

谢谢!

Zac*_*dds 1

目前尚不清楚你为什么在这里使用一个类。尝试例如

@pytest.mark.parametrize("p1", [True, False])
@pytest.mark.parametrize("p2", [True, False])
@given(ex=st.integers())
def test(p1, p2, ex):
    with setup_db(ex, (p1, p2)) as db:
        do_test_1(db)
        do_test_2(db)
        do_test_3(db)
Run Code Online (Sandbox Code Playgroud)

self(请注意,如果您在适当的位置添加 a,这也适用于测试方法)