有没有更简便的方法生成满足唯一性和全覆盖要求的复合值测试列表?
优化后的实现方案
核心优化点:用Hypothesis提供的@st.composite装饰器实现自定义生成策略,把原来嵌套的flatmap回调逻辑改成顺序执行的生成逻辑,可读性大幅提升。
from hypothesis import strategies as st from dataclasses import dataclass @dataclass class Thing: thing_id: str a: int b: float # 其他属性 @st.composite def thing_lists(draw, ab, max_extra_items=10): # ab 是给定的(a,b)配对列表,max_extra_items限制额外生成的元素数量,可按需调整 # 1. 生成最终的(a,b)序列:保证原ab所有配对至少出现1次,可额外重复任意配对 extra_abs = draw(st.lists(st.sampled_from(ab), max_size=max_extra_items)) all_abs = draw(st.permutations(ab + extra_abs)) # 2. 生成对应长度的唯一thing_id列表 unique_ids = draw(st.lists( st.text(), min_size=len(all_abs), max_size=len(all_abs), unique=True )) # 3. 直接生成Thing实例列表 things = [] for thing_id, (a, b) in zip(unique_ids, all_abs): thing = draw(st.builds( Thing, thing_id=st.just(thing_id), a=st.just(a), b=st.just(b) # 其余属性Hypothesis自动生成 )) things.append(thing) return things
使用示例
假设你有给定的ab配对列表:
from hypothesis import given test_ab = [(1, 2.0), (3, 4.0), (5, 6.0)] # 直接调用生成策略即可 @given(thing_lists(test_ab)) def test_your_logic(thing_list): # 你的测试逻辑 pass
优化说明
- 逻辑完全按常规思考顺序编写:先确定ab序列、再生成id、最后构造实例,没有嵌套回调,新手也能快速看懂
- 支持灵活控制额外生成的元素数量,避免生成过长的测试用例拖慢执行速度
- 无需手动拼接元组再转换为列表,直接在循环中构造
Thing实例即可
内容的提问来源于stack exchange,提问作者Andrea Reina
相关产品推荐
相关产品推荐

