property-based-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseProperty-Based Testing with Hypothesis
使用Hypothesis进行基于属性的测试
Discover edge cases automatically by testing properties instead of examples.
通过测试属性而非具体示例,自动发现边界情况。
Overview
概述
- Testing functions with many possible inputs
- Validating invariants that must hold for all inputs
- Finding boundary conditions and edge cases
- Testing serialization/deserialization roundtrips
- Stateful testing of APIs and state machines
- 测试存在大量可能输入的函数
- 验证对所有输入都成立的不变量
- 寻找边界条件和极端场景
- 测试序列化/反序列化往返流程
- 对API和状态机进行有状态测试
Quick Reference
快速参考
Example-Based vs Property-Based
基于示例的测试 vs 基于属性的测试
python
undefinedpython
undefinedExample-based: Test specific inputs
基于示例:测试特定输入
def test_sort_examples():
assert sort([3, 1, 2]) == [1, 2, 3]
# But what about [-1], [1.5, 2.5], ...?
def test_sort_examples():
assert sort([3, 1, 2]) == [1, 2, 3]
# 但像[-1]、[1.5,2.5]这些情况呢?
Property-based: Test properties for ALL inputs
基于属性:测试适用于所有输入的属性
from hypothesis import given
from hypothesis import strategies as st
@given(st.lists(st.integers()))
def test_sort_properties(lst):
result = sort(lst)
assert len(result) == len(lst) # Same length
assert all(result[i] <= result[i+1] for i in range(len(result)-1)) # Ordered
See [strategies-guide.md](references/strategies-guide.md) for complete strategy reference.from hypothesis import given
from hypothesis import strategies as st
@given(st.lists(st.integers()))
def test_sort_properties(lst):
result = sort(lst)
assert len(result) == len(lst) # 长度一致
assert all(result[i] <= result[i+1] for i in range(len(result)-1)) # 结果有序
完整的策略参考请查看[strategies-guide.md](references/strategies-guide.md)。Common Strategies
常用策略
python
from hypothesis import strategies as st
st.integers(min_value=0, max_value=100) # Bounded integers
st.text(min_size=1, max_size=50) # Bounded text
st.lists(st.integers(), max_size=10) # Bounded lists
st.from_regex(r"[a-z]+@[a-z]+\.[a-z]+") # Pattern-basedpython
from hypothesis import strategies as st
st.integers(min_value=0, max_value=100) # 有界整数
st.text(min_size=1, max_size=50) # 有界文本
st.lists(st.integers(), max_size=10) # 有界列表
st.from_regex(r"[a-z]+@[a-z]+\.[a-z]+") # 基于正则模式Composite for domain objects
用于领域对象的复合策略
@st.composite
def user_strategy(draw):
return User(
name=draw(st.text(min_size=1, max_size=50)),
age=draw(st.integers(min_value=0, max_value=150)),
)
undefined@st.composite
def user_strategy(draw):
return User(
name=draw(st.text(min_size=1, max_size=50)),
age=draw(st.integers(min_value=0, max_value=150)),
)
undefinedCommon Properties
常用属性
python
undefinedpython
undefinedRoundtrip (encode/decode)
往返测试(编码/解码)
@given(st.dictionaries(st.text(), st.integers()))
def test_json_roundtrip(data):
assert json.loads(json.dumps(data)) == data
@given(st.dictionaries(st.text(), st.integers()))
def test_json_roundtrip(data):
assert json.loads(json.dumps(data)) == data
Idempotence
幂等性
@given(st.text())
def test_normalize_idempotent(text):
assert normalize(normalize(text)) == normalize(text)
@given(st.text())
def test_normalize_idempotent(text):
assert normalize(normalize(text)) == normalize(text)
Oracle (compare to known implementation)
参照测试(与已知实现对比)
@given(st.lists(st.integers()))
def test_sort_matches_builtin(lst):
assert our_sort(lst) == sorted(lst)
See [stateful-testing.md](references/stateful-testing.md) for state machine testing.@given(st.lists(st.integers()))
def test_sort_matches_builtin(lst):
assert our_sort(lst) == sorted(lst)
状态机测试相关内容请查看[stateful-testing.md](references/stateful-testing.md)。Key Decisions
关键决策
| Decision | Recommendation |
|---|---|
| Strategy design | Composite strategies for domain objects |
| Example count | 100 for CI, 10 for dev, 1000 for release |
| Database tests | Use explicit mode, limit examples |
| Deadline | Disable for slow tests, 200ms default |
| Stateful tests | RuleBasedStateMachine for state machines |
| 决策项 | 推荐方案 |
|---|---|
| 策略设计 | 为领域对象使用复合策略 |
| 示例数量 | CI环境用100个,开发环境用10个,发布环境用1000个 |
| 数据库测试 | 使用显式模式,限制示例数量 |
| 超时时间 | 慢测试禁用,默认200毫秒 |
| 有状态测试 | 为状态机使用RuleBasedStateMachine |
Anti-Patterns (FORBIDDEN)
反模式(禁止使用)
python
undefinedpython
undefinedNEVER ignore failing examples
绝对不要忽略失败的示例
@given(st.integers())
def test_bad(x):
if x == 42:
return # WRONG - hiding failure!
@given(st.integers())
def test_bad(x):
if x == 42:
return # 错误 - 隐藏了失败情况!
NEVER use filter with low hit rate
绝对不要使用命中率极低的filter
st.integers().filter(lambda x: x % 1000 == 0) # WRONG - very slow
st.integers().filter(lambda x: x % 1000 == 0) # 错误 - 速度极慢
NEVER test with unbounded inputs
绝对不要使用无界输入进行测试
@given(st.text()) # WRONG - includes 10MB strings
def test_username(name):
User(name=name)
@given(st.text()) # 错误 - 会生成10MB大小的字符串
def test_username(name):
User(name=name)
NEVER mutate strategy results
绝对不要修改策略生成的结果
@given(st.lists(st.integers()))
def test_mutating(lst):
lst.append(42) # WRONG - mutates generated data
undefined@given(st.lists(st.integers()))
def test_mutating(lst):
lst.append(42) # 错误 - 修改了生成的数据
undefinedRelated Skills
相关技能
- - Custom markers and parallel execution
pytest-advanced - - Basic testing patterns
unit-testing - - API contract testing with Pact
contract-testing
- - 自定义标记与并行执行
pytest-advanced - - 基础测试模式
unit-testing - - 使用Pact进行API契约测试
contract-testing
References
参考资料
- Strategies Guide - Complete strategy reference
- Stateful Testing - State machine patterns
- Hypothesis Conftest - Production setup
- 策略指南 - 完整的策略参考
- 有状态测试 - 状态机模式
- Hypothesis Conftest - 生产环境配置
Capability Details
能力详情
strategies
strategies
Keywords: strategy, hypothesis, generator, from_type, composite
Solves: Generate test data, create strategies for custom types
关键词: strategy, hypothesis, generator, from_type, composite
解决问题: 生成测试数据,为自定义类型创建策略
properties
properties
Keywords: property, invariant, roundtrip, idempotent, oracle
Solves: What properties to test, roundtrips, invariants
关键词: property, invariant, roundtrip, idempotent, oracle
解决问题: 确定测试属性、往返测试、不变量验证
stateful
stateful
Keywords: stateful, state machine, RuleBasedStateMachine, rule
Solves: Test stateful systems, model state transitions
关键词: stateful, state machine, RuleBasedStateMachine, rule
解决问题: 测试有状态系统,建模状态转换
schemathesis
schemathesis
Keywords: schemathesis, openapi, api testing, fuzzing
Solves: Fuzz test API endpoints, generate from OpenAPI spec
关键词: schemathesis, openapi, api testing, fuzzing
解决问题: 模糊测试API端点,根据OpenAPI规范生成测试用例
hypothesis-settings
hypothesis-settings
Keywords: max_examples, deadline, profile, suppress_health_check
Solves: Configure for CI vs dev, speed up slow tests
关键词: max_examples, deadline, profile, suppress_health_check
解决问题: 为CI与开发环境配置参数,加速慢测试