为什么我的简单的有限假设检验永远不会停止?

时间:2019-07-01 07:31:23

标签: python pytest python-hypothesis

我正在运行一个假设为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分钟的测试后,我将其杀死了。)

如果我中断测试,追溯的痕迹似乎表明它只是不断产生新的例子。

我在这里做错了什么?

2 个答案:

答案 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