【问题标题】:Python hypothesis: Ensure that input lists have same lengthPython假设:确保输入列表具有相同的长度
【发布时间】:2019-01-06 21:13:35
【问题描述】:

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

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) 过滤掉太多输入的假设。所以我想生成一个随机正数并将其用作xy 的长度。有没有办法做到这一点?

【问题讨论】:

  • 那么当你选择这个随机的正数时,你想对列表做些什么来使它们符合

标签: python testing python-hypothesis


【解决方案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 将不提供任何信息。

【讨论】:

    【解决方案2】:

    我使用 @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
    

    【讨论】:

    • 这将返回一个在两个位置都有一个列表的元组 - 您可能希望删除 draw() 调用,以便 fixed_length_list 是一种策略,然后是 return (draw(ffl), draw(ffl))
    • @ZacHatfield-Dodds 会导致测试用例发生变化吗?我不完全理解 draw() 是如何工作的。
    【解决方案3】:

    您可以使用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))
    

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

    【讨论】:

      猜你喜欢
      • 2014-07-04
      • 2018-02-05
      • 2020-06-27
      • 2022-01-23
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      • 2018-09-01
      • 2012-05-15
      相关资源
      最近更新 更多