3

我有 3 个文件 module.py,其中包含一个示例函数,用于测试输入是否为数字。我有一个名为 test_mymodule_long.py 的文件,它使用py.testhypothesis成功测试并传递了几种类型的输入。我使用的是 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 函数会以不同的方式编程(假设你真的需要这样的函数)。我也知道这里指出的测试还不够完整,无法知道它是否有效。这些只是让我的问题清楚的例子。

4

1 回答 1

4

没有办法对单个测试使用多种策略,但您可以将多种策略组合成一个并在您的测试中使用它 -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)
于 2017-09-22T15:25:17.703 回答