用途
本技能用于在 Python 项目中开展基于属性的测试(Property-Based Testing),核心工具是 Hypothesis。它把“这里有几个应该通过的示例”转变为“这里有一条应当永远成立的属性”,由 Hypothesis 自动生成大量输入来寻找反例。
主要能力
- 安装 Hypothesis 并加入项目依赖。
- 将示例测试改写为属性测试。
- 选择合适的策略(strategies)生成数据。
- 使用 @composite 构建领域专用的自定义策略。
- 与 pytest 集成,支持 fixture、命令行选项与统计输出。
- 与 pytest-asyncio 结合进行异步属性测试。
- 自动支持 Pydantic 模型,并遵循其字段约束。
- 通过 profile 配置开发、CI、thorough 等不同测试强度。
- 支持状态机测试,用于测试状态机与复杂工作流。
- 失败时自动收缩(shrinking),给出最小反例。
核心概念
- 策略(Strategies):描述 Hypothesis 应生成的数据类型,如 st.integers()、st.text()、st.lists()、st.dictionaries()、st.one_of()、st.uuids()、st.datetimes() 等。
- @given 装饰器:用生成的数据运行测试函数,默认运行 100 个示例。
- 收缩(Shrinking):发现失败后自动最小化输入,例如报告 lst=[-1] 而非复杂的随机用例。
- 自定义策略:用 @composite 构建复杂领域对象,如生成合法邮箱地址。
使用方式
- 安装:uv add --dev hypothesis,并用 python -c "import hypothesis; print(hypothesis.version)" 验证。
- 识别要测试的属性:不变量、往返、幂等性、交换律、一致性。
- 选择策略:将数据类型映射到对应策略,如 List[int] → st.lists(st.integers())。
- 编写属性测试,例如用 @given(st.dictionaries(st.text(), st.text())) 测试 JSON 往返。
- 运行:pytest tests/test_properties.py -v;可用 --hypothesis-show-statistics 查看统计,用 --hypothesis-seed=12345 复现失败。
- 按需细化:为策略添加约束,谨慎使用 assume() 过滤,或用 @composite 创建自定义策略。
常见属性模式
- 往返测试:序列化后再反序列化应等于原对象。
- 不变量测试:某属性应始终成立,如排序后升序。
- 幂等性测试:操作两次等于操作一次。
- 交换律测试:顺序不影响结果,如 a + b == b + a。
- 一致性测试:不同路径得到相同结果。
集成与配置
- 与 pytest 无缝协作;fixture 每个测试函数调用一次,而非每个 Hypothesis 示例调用一次。
- 异步测试需注意装饰器顺序:@pytest.mark.asyncio 在最内层,@given 在最外层。
- Pydantic 模型可用 builds(MyModel) 自动生成,并可覆盖特定字段。
- 在 conftest.py 中注册 profile,如 ci(max_examples=200, deadline=1000)、dev(max_examples=50, deadline=None)、thorough(max_examples=1000, deadline=None, suppress_health_check=[HealthCheck.too_slow]),并通过环境变量加载。
- 常用配置项:max_examples(默认 100)、deadline(默认 200ms)、suppress_health_check、verbosity、randomize。
适用场景
- 手动编写大量相似示例测试时。
- 测试解析/序列化(往返属性)。
- 验证配置类,尤其是 Pydantic 模型。
- 测试具有数学性质的算法。
- 协议消息处理(IPC、API 请求/响应)。
- 状态机行为。
- 边界用例遗漏、需要更全面输入覆盖、验证重构后行为时。
限制与注意事项
- 应避免过度使用 assume() 过滤,否则会拖慢测试;优先在策略中加约束。
- 异步测试若装饰器顺序错误,会报“Hypothesis doesn't know how to run async test functions”。
- 具体安装命令、配置项默认值等以资料所述为准;资料未提供的功能、收费、价格、平台或效果暂未提供。