如何用Hypothesis生成含可选键的合法字典测试数据?
用Hypothesis生成符合JSON Schema的可选键组合字典
你这个复合策略的思路真的太对了!之前用fixed_dictionaries给可选键绑定st.one_of(st.none(), ...)的写法确实踩了坑——我们要的是直接移除可选键,而不是留着键却给个None值,你的拆分方法完美解决了这个问题,还避免了类型不匹配的风险。
先拆解下你的思路为什么好用:
- 首先用
fixed_dictionaries生成必填字段的基础字典,确保_id、username、social这三个核心键一定会存在,且类型完全符合要求。 - 把可选字段按数据类型拆分:
optional_strs专门处理字符串类型的可选键api_name,optional_ints处理整数类型的profile_id。这里用st.dictionaries配合st.just非常巧妙——因为Hypothesis的dictionaries策略默认min_size=0,所以会随机生成空字典或者包含指定键的字典,刚好对应“可选键不存在”或“可选键存在且类型正确”的两种情况。 - 最后通过字典解包合并所有部分,得到的结果完全符合目标JSON Schema的所有合法情况。
这里是你的完整可运行代码:
import hypothesis.strategies as st @st.composite def generate_data(draw): base_data = st.fixed_dictionaries({ '_id': st.text(), 'username': st.text(), 'social': st.text(), }) optional_strs = st.dictionaries( keys=st.just('api_name'), values=st.text() ) optional_ints = st.dictionaries( keys=st.just('profile_id'), values=st.integers() ) b = draw(base_data) s = draw(optional_strs) i = draw(optional_ints) return {**b, **s, **i}
这个策略会自动生成所有合法的字典组合:
- 仅含必填键的基础字典
- 必填键 +
api_name的组合 - 必填键 +
profile_id的组合 - 包含所有必填键和两个可选键的完整字典
完全满足你对目标JSON Schema的测试数据生成需求,不会出现键存在但值为None的无效情况,也不会有类型不匹配的问题。
内容的提问来源于stack exchange,提问作者Milo
相关产品推荐
相关产品推荐

