5

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

如果我中断测试,回溯似乎表明它只是不断地生成新的例子。

我在这里做错了什么?

4

2 回答 2

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…]

看,这部分文档,例如,成功的测试用例的默认数量应该是 100。因此,试图生成越来越多的数据以仅限制为 6 个用例很快就无法找到这 6 个用例之一。

最简单的方法可以是仅限制此测试通过所需的示例数量:

>>> 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运行那些显式示例

>>> 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))选择一种方法并坚持下去,但不要混合使用它们。

于 2019-07-01T07:55:27.867 回答
1

这个错误已在假设4.26.2中得到修复,或者至少我们是这么认为的;它实际上已在 4.26.3 中修复:https ://hypothesis.readthedocs.io/en/latest/changes.html#v4-26-3

于 2019-07-04T19:37:54.187 回答