为什么我的简单、有限的假设检验永远不会停止?
Why does my simple, finite hypothesis test never stop?
我正在 运行使用 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 分钟的测试后,我将其杀死。)
如果我中断测试,回溯痕迹似乎表明它只是不断地产生新的例子。
我做错了什么?
这似乎与 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
and ask hypothesis
to 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))
,因此请选择一种方法并坚持使用,但不要混用。
这个错误已在假设 4.26.2 中修复,或者至少我们是这么认为的; 实际上 已在 4.26.3 中修复:https://hypothesis.readthedocs.io/en/latest/changes.html#v4-26-3
我正在 运行使用 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 分钟的测试后,我将其杀死。)
如果我中断测试,回溯痕迹似乎表明它只是不断地产生新的例子。
我做错了什么?
这似乎与 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
and ask hypothesis
to 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))
,因此请选择一种方法并坚持使用,但不要混用。
这个错误已在假设 4.26.2 中修复,或者至少我们是这么认为的; 实际上 已在 4.26.3 中修复:https://hypothesis.readthedocs.io/en/latest/changes.html#v4-26-3