Python 假设:确保输入列表具有相同的长度

Ver*_*ion 8 python testing python-hypothesis

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

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
Run Code Online (Sandbox Code Playgroud)

这给了我错误信息:

FailedHealthCheck:看起来您的策略正在过滤掉大量数据。健康检查发现了 50 个过滤的示例,但只有 4 个很好的示例。

len(x) == len(y)过滤掉太多输入的假设。所以我想产生一个随机正数和使用,作为两者的长度xy。有没有办法做到这一点?

Ver*_*ion 8

我使用@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
Run Code Online (Sandbox Code Playgroud)

  • `draw(...)` 将返回一个可以由策略生成的示例。但是如果你想要两个相同长度的不同列表,你需要调用它两次 - 正如所写的,`x is y` 在你的测试中将是真的! (2认同)

Pat*_*ugh 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))
Run Code Online (Sandbox Code Playgroud)

这有点笨拙,我对不得不在测试体中解压列表不太高兴。