如何使用假设的复合策略执行Python函数?

我正在尝试执行一个用Hypothesis'@strategy.composite装饰器修饰的函数。

我知道我可以使用@given装饰器来测试功能,例如-

from hypothesis import given
from hypothesis import strategies as st

@given(st.integers(min_value=1))
def test_bar(x):
    assert x > 0

pytest使用-pytest <filename.py>

但是对于带有@strategy.composite装饰器的函数,例如-

from hypothesis import strategies as st
from hypothesis import given
import pytest

@st.composite
def test_foo(draw):
    arg1 = draw(st.integers(min_value=1))
    arg2 = draw(st.lists(st.integers(),min_size=arg1,max_size=arg1))
    print(arg1," ",arg2)
    assert(len(arg2) == arg1)

我无法以类似方式执行测试。
使用pytest时,我无法执行测试(使用python执行python文件不会执行任何操作)-

[reik@reik-msi tests]$ pytest testhypo.py
==================================== test session starts ====================================
platform linux -- Python 3.8.3,pytest-5.4.3,py-1.8.1,pluggy-0.13.1
rootdir: /home/reik/tests
plugins: hypothesis-5.16.0,lazy-fixture-0.6.3
collected 1 item                                                                            

testhypo.py F                                                                         [100%]

========================================= FAILURES ==========================================
_________________________________________ test_foo __________________________________________

item = <Function test_foo>

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_call(item):
        if not hasattr(item,"obj"):
            yield
        elif not is_hypothesis_test(item.obj):
            # If @given was not applied,check whether other hypothesis
            # decorators were applied,and raise an error if they were.
            if getattr(item.obj,"is_hypothesis_strategy_function",False):
>               raise InvalidArgument(
                    "%s is a function that returns a Hypothesis strategy,but pytest "
                    "has collected it as a test function.  This is useless as the "
                    "function body will never be executed.  To define a test "
                    "function,use @given instead of @composite." % (item.nodeid,)
                )
E               hypothesis.errors.InvalidArgument: testhypo.py::test_foo is a function that returns a Hypothesis strategy,but pytest has collected it as a test function.  This is useless as the function body will never be executed.  To define a test function,use @given instead of @composite.

/usr/lib/python3.8/site-packages/hypothesis/extra/pytestplugin.py:132: InvalidArgument
================================== short test summary info ==================================
FAILED testhypo.py::test_foo - hypothesis.errors.InvalidArgument: testhypo.py::test_foo is...
===================================== 1 failed in 0.06s =====================================

我尝试添加函数调用test_foo(),但遇到相同的错误。

然后我尝试在函数上方添加@given并收到另一个错误-

========================================== ERRORS ===========================================
________________________________ ERROR at setup of test_foo _________________________________
file /usr/lib/python3.8/site-packages/hypothesis/core.py,line 903
      def run_test_as_given(test):
E       fixture 'test' not found
>       available fixtures: cache,capfd,capfdbinary,caplog,capsys,capsysbinary,doctest_namespace,monkeypatch,pytestconfig,record_property,record_testsuite_property,record_xml_attribute,recwarn,tmp_path,tmp_path_factory,tmpdir,tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/usr/lib/python3.8/site-packages/hypothesis/core.py:903
================================== short test summary info ==================================
ERROR testhypo.py::test_foo

如果我使用@given()-请注意多余的花括号,而是出现另一个错误-

========================================= FAILURES ==========================================
_________________________________________ test_foo __________________________________________

arguments = (),kwargs = {}

    def wrapped_test(*arguments,**kwargs):
>       raise InvalidArgument(message)
E       hypothesis.errors.InvalidArgument: given must be called with at least one argument

/usr/lib/python3.8/site-packages/hypothesis/core.py:234: InvalidArgument
================================== short test summary info ==================================
FAILED testhypo.py::test_foo - hypothesis.errors.InvalidArgument: given must be called wit...

我尝试将代码包装在另一个函数中-

from hypothesis import strategies as st
from hypothesis import given
import pytest

def demo():
    @st.composite
    def test_foo(draw):
        arg1 = draw(st.integers(min_value=1))
        arg2 = draw(st.lists(st.integers(),max_size=arg1))
        print(arg1,arg2)
        assert(len(arg2) == arg1)

但这也不起作用-

[reik@reik-msi tests]$ python testhypo.py
[reik@reik-msi tests]$ pytest testhypo.py
==================================== test session starts ====================================
platform linux -- Python 3.8.3,lazy-fixture-0.6.3
collected 0 items                                                                           

=================================== no tests ran in 0.00s ===================================

(我还尝试将demo函数调用放在文件末尾,但这丝毫没有改变测试行为)

Hypothesis quick start guide说,调用该函数可以工作,但显然不行。 (为了公平起见,文档未指定如何使用@composite运行测试)

如何测试用@strategy.composite装饰的功能?我没有使用pytest-我宁愿不必实际使用它,但这似乎是测试功能(以@given装饰)的最简单方法,因此我决定走那条路。

iCMS 回答:如何使用假设的复合策略执行Python函数?

@st.composite是用于定义自定义策略(而非测试)的辅助功能。

您要尝试执行的操作可以通过使用@givenst.data()来完成:

@given(st.data())
def test_foo(data):
    x = data.draw(st.integers())
    ...

https://hillelwayne.com/post/property-testing-complex-inputs/很好地概述了如何使用这些技术。

本文链接:https://www.f2er.com/2051503.html

大家都在问