9

我正在使用假设来测试一个将两个长度相等的列表作为输入的函数。

import hypothesis.strategies as st
from hypothesis import assume, given


@given(st.lists(ints, min_size=1),
       st.lists(ints, min_size=1),
       )
def test_my_func(x, y):
    assume(len(x) == len(y))

    # Assertions

这给了我错误信息:

FailedHealthCheck:您的策略似乎过滤掉了大量数据。健康检查发现了 50 个过滤示例,但只有 4 个好的示例。

len(x) == len(y)过滤掉太多输入的假设。所以我想生成一个随机正数并将其用作 和 的x长度y。有没有办法做到这一点?

4

3 回答 3

10

@composite我使用装饰器找到了答案。

import hypothesis.strategies as st
from hypothesis import given

@st.composite
def same_len_lists(draw):

    n = draw(st.integers(min_value=1, max_value=50))
    fixed_length_list = st.lists(st.integers(), min_size=n, max_size=n)

    return (draw(fixed_length_list), draw(fixed_length_list))


@given(same_len_lists())
def test_my_func(lists):

    x, y = lists

    # Assertions
于 2018-07-30T17:34:26.677 回答
6

您可以使用flatmap来生成依赖于其他生成数据的数据。

import hypothesis.strategies as st
from hypothesis import assume, given
from hypothesis.strategies import integers as ints

same_len_lists = ints(min_value=1, max_value=100).flatmap(lambda n: st.lists(st.lists(ints(), min_size=n, max_size=n), min_size=2, max_size=2))

@given(same_len_lists)
def test_my_func(lists):
    x, y = lists
    assume(len(x) == len(y))

这有点笨拙,而且我对必须解压缩测试体内的列表感到不太高兴。

于 2018-07-30T15:57:19.753 回答
1

其他解决方案提供了很好的可重用策略。这是一个简短的低技术解决方案,可能更适合一次性使用,因为您需要在测试功能中进行一行处理。我们使用 zip 转置一组对(2 元素元组);从概念上讲,我们正在将n x 2矩阵转换为2 x n矩阵。

import hypothesis.strategies as st
from hypothesis import given

pair_lists = st.lists(st.tuples(st.integers(), st.integers()), min_size=1)

@given(pair_lists)
def test_my_func(L):
    x, y = map(list, zip(*L))

警告:拥有是至关重要的,min_size=1因为zip如果列表为空,将不会给出任何内容。

于 2020-11-19T06:28:46.740 回答