我正在运行一个假设为4.24.6和pytest-5.0.0的测试套件。我的测试只有一组有限的可能输入,但是假设永远无法完成测试。
我将其简化为以下最小示例,我以pytest test.py
from hypothesis import given
import hypothesis.strategies as st
@given(x=st.just(0)
| st.just(1),
y=st.just(0)
| st.just(1)
| st.just(2))
def test_x_y(x, y):
assert True
我希望它会在这里尝试所有六个组合,然后成功。或者可能是检查薄脆性的一小部分。相反,它会无限期运行(在大约15分钟的测试后,我将其杀死了。)
如果我中断测试,追溯的痕迹似乎表明它只是不断产生新的例子。
我在这里做错了什么?
答案 0 :(得分:3)
这似乎与hypothesis
尝试生成的成功测试的数量有关:
>>> from hypothesis import given, strategies as st
>>> @given(st.integers(0,1), st.integers(0,2))
... def test(x, y):
... print(x, y)
... assert True
...
>>> test()
0 0
1 1
1 0
1 2
1 1
0 1
0 0
1 2
0 2
0 2
1 0
1 2
0 1
0 1
1 2
[snip…]
请参见this part of the docs, for instance,成功的测试用例的默认数量应为100。因此,试图生成越来越多的数据以仅将其限制为6个案例,很快就无法找到这6个案例之一。
最简单的方法可能只是通过此测试所需的limit the amount of examples:
>>> from hypothesis import settings
>>> @settings(max_examples=30)
... @given(st.integers(0,1), st.integers(0,2))
... def test(x, y):
... print(x, y)
... assert True
...
>>> test()
0 0
1 1
1 0
0 2
1 2
0 1
0 1
1 1
1 0
1 1
0 1
1 2
1 1
0 0
0 2
0 2
0 0
1 2
1 0
0 1
1 0
1 0
0 1
1 2
1 1
0 2
0 0
1 2
0 0
0 2
鉴于测试用例数量很少,另一种方法是使用@example
明确显示所有测试用例,并要求hypothesis
选择only run those explicit examples:
>>> from hypothesis import given, example, settings, Phase, strategies as st
>>> @settings(phases=(Phase.explicit,))
... @given(x=st.integers(), y=st.integers())
... @example(x=0, y=0)
... @example(x=0, y=1)
... @example(x=0, y=2)
... @example(x=1, y=0)
... @example(x=1, y=1)
... @example(x=1, y=2)
... def test(x, y):
... print(x, y)
... assert True
...
>>> test()
0 0
0 1
0 2
1 0
1 1
1 2
还要注意,st.just(0) | st.just(1)
与st.one_of(st.just(0), st.just(1))
等效,因此请选择一种方法并坚持使用,但不要混淆。
答案 1 :(得分:1)
此错误已在假设 4.26.2 中修复,或者至少我们是这样认为的;它实际上已在4.26.3中被 修复:https://hypothesis.readthedocs.io/en/latest/changes.html#v4-26-3