Hypothesis 属性测试入门指南(Python)

Hypothesis 是 Python 的属性测试(Property-based Testing)库,能自动生成海量测试用例并自动缩小反例。本文讲解 @given、strategies、与 pytest 集成及有状态测试的用法。

最佳实践
测试检测与质量验证插画

本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。

直接回答:Hypothesis 是 Python 生态中最知名的属性测试库:你不再手写一个个具体用例,而是描述"输入应该满足什么约束、输出应该满足什么性质",由库自动生成成百上千个用例去验证,一旦发现反例还会自动缩小到较简单的形式。

从例子测试到属性测试

传统单元测试是"举例式"的:给 add(1, 2) 断言等于 3。问题在于你只能验证想到的那几个例子。属性测试换了个思路——断言性质:

  • 对任意两个数,add(a, b) == add(b, a)(交换律)
  • 对任意列表,sorted(sorted(xs)) == sorted(xs)(幂等性)
  • 对任意合法输入,解析再序列化应当等价(往返一致性)

快速上手

pip install hypothesis
from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_sort_idempotent(xs):
    assert sorted(sorted(xs)) == sorted(xs)

运行时 Hypothesis 会自动生成空列表、单元素、极大极小整数、重复元素等各种"刁钻"输入。如果断言失败,它会不断简化输入,尝试给出较小反例;受测试预算和策略影响,不保证数学意义的全局最小。

strategies:描述输入空间

常用策略:

策略 含义
st.integers(min_value=0, max_value=100) 限定范围的整数
st.text(alphabet="abc", max_size=10) 限定字符集与长度的字符串
st.datetimes(timezones=st.timezones()) 带时区的日期时间;默认 st.datetimes() 生成 naive datetime
st.builds(MyClass, field=st.integers()) 构造自定义对象
st.one_of(a, b) / s.filter(...) / s.map(...) 组合、过滤、变换策略

策略定义得越贴近真实数据分布,测试价值越高。

与 pytest 集成

Hypothesis 天然兼容 pytest,@given 装饰的函数可以像普通测试一样被收集;配合 @settings(max_examples=500, deadline=None) 可以控制用例预算和 deadline 检查(不是强制中断死循环的硬超时)。函数级 fixture 不会为每个生成样本重新初始化;数据库资源须在每个样本内创建/回滚,避免状态污染:

from hypothesis import settings

@settings(max_examples=200)
@given(email=st.emails())
def test_create_user(email):
    # isolated_test_db 是项目实现的上下文管理器,退出时回滚/清理。
    with isolated_test_db() as db:
        assert create_user(db, email).email == email

有状态测试(Rule-based)

对于"一连串操作"的系统(缓存、队列、状态机),Hypothesis 提供 RuleBasedStateMachine:定义若干操作规则和不变量,库会自动生成随机操作序列,尝试把系统搞坏——这是普通参数化测试很难覆盖的维度。

常见问题(FAQ)

Q:属性测试会不会很慢?
A:比单条用例慢是肯定的,但 max_examples 可调,默认 max_examples 通常为100,是否足够取决于输入空间;CI 可增加预算。它不是穷举,也不保证覆盖率固定倍数提升。

Q:找不到"性质"可断言怎么办?
A:最常见的万能性质是"不抛异常"和"往返一致"(parse∘serialize = identity)。从这两个入手,慢慢就能发现更多业务不变量。

Q:Hypothesis 发现的反例能固定下来吗?
A:可以。库自带 example 数据库会记住失败用例,修复后建议顺手补一条普通的参数化测试做回归。

官方参考

资料核对日期:2026-09-29。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台