python假设中相同函数参数的多种策略

Mat*_*hio 5 python pytest python-hypothesis

我正在使用Hypothesis包用 Python 编写一个简单的测试代码。有没有办法对同一个函数参数使用多种策略?例如,使用integers()floats()来测试我的values参数而不编写两个单独的测试函数?

from hypothesis import given
from hypothesis.strategies import lists, integers, floats, sampled_from
@given(
    integers() ,floats()
)
def test_lt_operator_interval_bin_numerical(values):
    interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
    assert (interval_bin < values) == (interval_bin.right < values)
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用,但它代表了我想要实现的目标。

注意:我已经尝试过使用两种不同策略创建两个不同测试的简单解决方案:

def _test_lt(values):
    interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
    assert (interval_bin < values) == (interval_bin.right < values)

test_lt_operator_interval_bin_int = given(integers())(_test_lt)

test_lt_operator_interval_bin_float = given(floats())(_test_lt)
Run Code Online (Sandbox Code Playgroud)

然而我想知道是否有更好的方法来做到这一点:当策略的数量变大时,它作为代码是相当冗余的。

Aza*_*kov 5

一般来说,如果您需要您的值是几个事物之一(例如您示例中的ints 或floats ),那么我们可以将单独事物的策略组合成一个 with|运算符(其操作类似于sets 的操作 - 一个联合运算符,其工作原理是调用__or__魔术方法):

from hypothesis import given
from hypothesis.strategies import integers, floats
@given(
    integers() | floats()
)
def test_lt_operator_interval_bin_numerical(values):
    interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
    assert (interval_bin < values) == (interval_bin.right < values)
Run Code Online (Sandbox Code Playgroud)

或者你可以使用strategies.one_of@Zac Hatfield-Dodds 提到的,它的作用几乎相同:

from hypothesis import given
from hypothesis.strategies import integers, floats, one_of
@given(
    one_of(integers(), floats())
)
def test_lt_operator_interval_bin_numerical(values):
    interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
    assert (interval_bin < values) == (interval_bin.right < values)
Run Code Online (Sandbox Code Playgroud)