使用pytest与Hypothesis自动生成Address数据类实例失败求助
如何让Hypothesis自动生成attrs数据类的测试策略?
问题背景
你已通过手动定义st.builds()策略成功让Hypothesis捕获到Address类的测试bug,但尝试st.register_type_strategy(Address)或直接@given(Address)时,无法实现自动生成策略的效果。
问题根源
st.register_type_strategy用法错误:该函数要求传入「目标类 + 对应的策略实例」,而非仅传入类本身- 直接传入类不生效:Hypothesis不会自动将类对象解析为测试策略,需明确触发类型推导逻辑
正确解决方案
方案1:使用st.from_type()自动推导(推荐)
这是最简洁的方式,Hypothesis会根据类的类型注解自动生成匹配的策略,完美支持attrs数据类:
import attrs from hypothesis import given import hypothesis.strategies as st @attrs.frozen(kw_only=True) class Address: street: str city: str # 用st.from_type()自动推导Address的测试策略 @given(st.from_type(Address)) def test_proper_address(address): assert len(address.city) < 4
运行pytest后,会和手动定义策略一样捕获到city='0000'的反例。
方案2:正确注册全局类型策略
如果需要在多个测试中复用Address的策略,可以通过st.register_type_strategy()完成全局注册,注意必须传入策略实例:
import attrs from hypothesis import given import hypothesis.strategies as st @attrs.frozen(kw_only=True) class Address: street: str city: str # 注册Address类对应的策略 st.register_type_strategy(Address, st.builds(Address, street=st.text(), city=st.text())) # 后续测试可直接传入Address类 @given(Address) def test_proper_address(address): assert len(address.city) < 4
方案3:依赖自动识别(需环境达标)
确保你的环境满足以下条件时,Hypothesis可自动识别attrs类的策略:
- 安装最新版本的Hypothesis(内置attrs支持,无需额外依赖)
- 类的所有字段都有完整的类型注解
此时可通过隐式推导,但最可靠的仍是st.from_type()。
验证效果
无论使用哪种方案,运行pytest后都会得到相同的错误输出,成功捕获测试bug:
address = Address(street='', city='0000') @given(st.from_type(Address)) def test_proper_address(address): > assert len(address.city) < 4 E AssertionError: assert 4 < 4 E + where 4 = len('0000') E + where '0000' = Address(street='', city='0000').city main.py:23: AssertionError
内容的提问来源于stack exchange,提问作者OrenIshShalom
相关产品推荐
相关产品推荐

