我正在尝试执行一个用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(), min_size=arg1, 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, 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 0 items
=================================== no tests ran in 0.00s ===================================
(我也尝试将demo
函数调用放在文件末尾,但这并没有以任何方式改变测试行为)
假设快速入门指南说调用该函数会起作用,但显然不起作用。(公平地说,文档没有指定如何使用 运行测试@composite
)
如何测试用 装饰的功能@strategy.composite
?我不必使用 pytest - 我宁愿不必实际使用它,但它似乎是测试功能(用 装饰@given
)最简单的方法,所以我决定走那条路。