使用假设和 py.test 来测试 python 中的复合策略,我必须一次测试它们吗?

Using hypothesis and py.test to test compound strategies in python, must I test them one at a time?

我有 3 个文件,module.py 其中包含一个测试输入是否为数字的示例函数。我有一个名为 test_mymodule_long.py 的文件,它 成功地 测试并使用 py.test and hypothesis 测试并传递了几种类型的输入。我正在使用 Python 3.6,但这应该无关紧要(如果你不是,只需删除类型提示)。对于这个特定的功能,将它们分开对我没有帮助;如果假设找到边缘情况,我只想知道有问题的输入和引发的异常。因此,我想按照 test_mymodule_short.py 中的指示编写此测试,但这不起作用。

我的问题是:有没有一种方法可以比 test_mymodule_long.py 更有效地在假设中编写策略?

这是每个文件中的代码:

'''
mymodule.py
'''

from typing import Union

Number = Union[int, float]


def is_numeric(x: Number):
    try:
        y = float(x)
        return True
    except:
        return False

# -------------------------------------------

'''
test_mymodule_long.py [This code works]
(using pytest to discover tests automatically)
'''
from hypothesis import given, example
import hypothesis.strategies as st
import mymodule

@given(st.integers())
def test_is_numeric_integer(num):
    result = stats.is_numeric(num)
    assert isinstance(result, bool)


@given(st.floats())
def test_is_numeric_float(num):
    result = stats.is_numeric(num)
    assert isinstance(result, bool)


@given(st.text())
def test_is_numeric_text(num):
    result = stats.is_numeric(num)
    assert isinstance(result, bool)


@given(st.lists(st.floats()))
def test_is_numeric_list(num):
    result = stats.is_numeric(num)
    assert isinstance(result, bool)

# -------------------------------------------

'''
test_mymodule_short.py [This code fails!]
(using pytest to discover tests automatically)
'''
from hypothesis import given, example
import hypothesis.strategies as st
import mymodule

@given(st.integers())
@given(st.floats())
@given(st.text())
@given(st.lists(st.floats()))
def test_is_numeric_list(num):
    result = mymodule.is_numeric(num)
    assert isinstance(result, bool)

请注意,我认为错误消息在这里并不重要,它更像是一种 这不是你怎么做的 情况,我'我正在寻求有关是否存在一种紧凑的方法来使用多个假设策略测试一个函数的建议。此外,我知道适当的 is_numeric 函数的编程方式会有所不同(假设您真的需要这样的函数)。我也知道这里指出的测试不够完整,无法知道它是否有效。这些只是让我的问题更清楚的例子。

无法对单个测试使用多个策略,但您可以将多个策略组合成一个并在测试中使用它 - one_of战略。所以你可以这样写:

from hypothesis import given, example
import hypothesis.strategies as st
import mymodule

@given(st.one_of(
    st.integers(), 
    st.floats(),
    st.text(),
    st.lists(st.floats()),
))
def test_is_numeric_list(num):
    result = mymodule.is_numeric(num)
    assert isinstance(result, bool)