You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Hypothesis生成长度依赖于另一生成参数的列表策略?

如何利用Hypothesis生成长度依赖于另一生成参数的列表策略?

嘿,我太懂你现在的困扰了——之前那种先生成最大长度列表再切片的方法,不仅慢得离谱,还触发了Hypothesis的健康检查提示,确实挺闹心的。其实你需要的是复合策略(composite strategies),这正是Hypothesis专门用来处理这种「参数互相依赖」场景的工具!

为什么之前的方法行不通?

你之前的思路是先造一个最长的列表再切片,本质上是让Hypothesis生成了大量不符合要求的候选数据,然后手动过滤掉多余部分。这种过滤行为会让Hypothesis做很多无用功:既拖慢了测试速度,又因为大部分生成的数据被丢弃,触发了它的健康检查机制——毕竟它会认为你在浪费生成资源。

正确解法:用@composite定义依赖策略

你可以用hypothesis.strategies.composite装饰器创建一个自定义策略,先生成整数x,再根据x的具体值生成长度恰好匹配的列表。这样生成的每一组数据都是完全符合要求的,没有任何过滤操作,自然解决了速度和健康检查的问题。

给你看个具体的代码示例:

from hypothesis import given, strategies as st

# 示例被测函数(和你的需求一致)
def your_target_function(x: int, l: list[float]) -> None:
    assert len(l) == x, "列表长度必须和x相等"

# 定义复合策略
@st.composite
def x_and_matching_length_list(draw):
    # 先生成x,你可以根据需求限定范围,比如正整数1到100
    x = draw(st.integers(min_value=1, max_value=100))
    # 再根据x生成长度严格等于x的float列表
    matching_list = draw(st.lists(st.floats(allow_nan=False), min_size=x, max_size=x))
    return x, matching_list

# 编写单元测试
@given(x_and_matching_length_list())
def test_target_function(x, l):
    your_target_function(x, l)

这个方法的优势一目了然:

  • 无过滤,速度拉满:每一次生成的列表长度都严格匹配x,不需要丢弃任何数据,测试效率直接提升。
  • 通过健康检查:因为没有过滤行为,Hypothesis不会再弹出那个烦人的警告。
  • 数据更精准:你可以完全控制x的取值范围,以及列表中float的生成规则(比如我上面加了allow_nan=False避免NaN干扰,你可以根据自己的需求调整)。

如果你的x有特殊取值限制(比如只能是偶数),直接在st.integers里做限定就行,复合策略会自动适配生成对应长度的列表。

备注:内容来源于stack exchange,提问作者Simon Peatman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 08:08:06