mcpField
P
property-based-testing

property-based-testing

github.com/laurigates测试与质量5972 次安装今天更新
代码仓库

关于 property-based-testing

为开发者提供基于生成输入验证性质与不变量的测试参考,而非只检查固定示例。内容涵盖 TypeScript/JavaScript 的 fast-check 和 Python 的 Hypothesis,包括缩减失败用例与状态测试。

主要功能

  1. 01生成测试输入
  2. 02缩减失败用例
  3. 03fast-check 与 Hypothesis 示例
  4. 04性质与不变量测试模式
  5. 05使用 Hypothesis 进行状态测试

适用场景

  1. 01检查编码与解码往返
  2. 02发现数据转换的边界情况
  3. 03用生成数据验证 API 契约
  4. 04针对不变量测试操作序列

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/laurigates/claude-plugins --skill property-based-testing

安装后在 Claude Code 中输入/property-based-testing确认已加载。

附带文件REFERENCE.md

详细介绍

基于属性的测试

基于属性的测试专业知识——自动生成测试用例,以验证代码属性,而非测试特定示例。

何时使用此技能

在以下情况使用此技能……在以下情况改用其他技能……
测试数学属性(交换律、结合律)编写基于特定示例的单元测试
测试编码/解码的往返过程设置测试运行器配置
自动查找边界情况进行端到端浏览器测试
验证数据转换和不变量分析测试质量或异味
使用生成的数据测试 API 契约运行变异测试

核心专业知识

基于属性的测试概念

  • 传统测试:测试特定示例
  • 基于属性的测试:测试应对所有输入成立的属性
  • 生成器:自动创建多样化的测试输入
  • 缩减:将失败用例缩减为最简单的示例
  • 覆盖率:探索人们可能忽略的边界情况

何时使用基于属性的测试

  • 数学运算(交换律、结合律等属性)
  • 编码器/解码器(往返属性)
  • 解析器和序列化器
  • 数据转换
  • API 契约
  • 不变量和约束

TypeScript/JavaScript(fast-check)

安装
# Using Bun
bun add -d fast-check

# Using npm
npm install -D fast-check
基本示例
import { test } from 'vitest'
import * as fc from 'fast-check'

// Property-based test
test('reverse twice returns original - property based', () => {
  fc.assert(
    fc.property(
      fc.array(fc.integer()), // Generate random arrays of integers
      (arr) => {
        expect(reverse(reverse(arr))).toEqual(arr)
      }
    )
  )
})
// fast-check automatically generates 100s of test cases!
关键生成器(速查)
生成器描述
fc.integer()任意整数(可选最小值/最大值)
fc.nat()自然数(>= 0)
fc.float() / fc.double()浮点数
fc.string()任意字符串(可选长度)
fc.emailAddress()符合电子邮件格式的字符串
fc.array(arb)任意类型的数组
fc.record({...})含有类型化字段的对象
fc.boolean()布尔值
fc.constantFrom(...)从选项中选取
fc.tuple(...)固定大小的元组
fc.oneof(...)联合类型
fc.option(arb)值或 null
fc.date()日期对象
常见测试属性
属性模式示例
往返f(g(x)) = x编码/解码、序列化/解析
幂等性f(f(x)) = f(x)排序、规范化、格式化
交换律f(a,b) = f(b,a)加法、合并、并集
结合律f(f(a,b),c) = f(a,f(b,c))加法、连接
单位元f(x, id) = x乘以 1、加 0
逆运算f(g(x)) = x加密/解密
配置
fc.assert(property, {
  numRuns: 1000,      // Run 1000 tests (default: 100)
  seed: 42,           // Reproducible tests
  endOnFailure: true, // Stop after first failure
})
前置条件
fc.pre(b !== 0) // Skip cases where b is 0

Python(Hypothesis)

安装
# Using uv
uv add --dev hypothesis pytest

# Optional extensions
uv add --dev hypothesis[numpy]   # NumPy strategies
uv add --dev hypothesis[django]  # Django model strategies
配置
# pyproject.toml
[tool.hypothesis]
max_examples = 200
deadline = 1000

[tool.hypothesis.profiles.dev]
max_examples = 50
deadline = 1000

[tool.hypothesis.profiles.ci]
max_examples = 500
deadline = 5000
verbosity = "verbose"
# Activate profile in conftest.py
from hypothesis import settings
settings.load_profile("ci")
基本示例
from hypothesis import given, example, assume
import hypothesis.strategies as st

# Test a property
@given(st.integers(), st.integers())
def test_addition_commutative(a, b):
    assert a + b == b + a

# Add explicit edge cases with @example
@given(st.integers())
@example(0)
@example(-1)
@example(2**31 - 1)
def test_with_explicit_examples(x):
    assert process(x) is not None
关键策略(速查)
策略描述
st.integers()任意整数(可选边界)
st.floats()浮点数
st.text()任意字符串(可选大小)
st.binary()字节字符串
st.lists(strat)由给定策略生成的列表
st.sets(strat)唯一值集合
st.dictionaries(k, v)字典
st.booleans()布尔值
st.sampled_from(...)从选项中选取
st.tuples(...)固定大小的元组
st.one_of(...)联合类型
st.emails()有效电子邮件地址
st.uuids()UUID 对象
st.dates() / st.datetimes()日期/时间值
st.builds(Class, ...)根据策略构建对象
配置(设置)
from hypothesis import given, settings, strategies as st

@settings(max_examples=1000, deadline=None)
@given(st.lists(st.integers()))
def test_with_custom_settings(arr):
    assert sort(arr) == sorted(arr)
假设
from hypothesis import assume
assume(b != 0)  # Skip cases where b is 0
有状态测试

Hypothesis 支持通过 RuleBasedStateMachine 进行有状态测试,用于针对不变量测试一系列操作。

CI 集成
# .github/workflows/test.yml
- name: Run hypothesis tests
  run: |
    uv run pytest \
      --hypothesis-show-statistics \
      --hypothesis-profile=ci \
      --hypothesis-seed=${{ github.run_number }}

- name: Upload hypothesis database
  uses: actions/upload-artifact@v4
  if: failure()
  with:
    name: hypothesis-examples
    path: .hypothesis/
速查
# Core decorators
@given(strategy)              # Generate test inputs
@example(value)               # Add explicit test case
@settings(max_examples=500)   # Configure behavior

# Key helpers
assume(condition)             # Skip invalid inputs
note(message)                 # Add debug info to failure output
target(value)                 # Guide generation toward value

面向 Agent 的优化

上下文命令
快速 TS 测试bunx vitest --dots --bail=1 --grep 'property'
快速 Python 测试uv run pytest -x -q --tb=short -k 'property'
CI TS 测试bunx vitest run --reporter=junit --grep 'property'
CI Python 测试uv run pytest --hypothesis-profile=ci --hypothesis-show-statistics -q
可复现fc.assert(prop, { seed: 42 }) 或 pytest --hypothesis-seed=42
快速迭代fc.assert(prop, { numRuns: 50 }) 或 pytest --hypothesis-profile=dev -x
调试失败项pytest -x -s --hypothesis-verbosity=debug
不进行缩减在 @settings 中添加 phases=[Phase.generate]

如需详细示例、高级模式和最佳实践,请参阅 REFERENCE.md。

另请参阅

  • vitest-testing - 单元测试框架
  • python-testing - Python pytest 测试
  • test-quality-analysis - 检测测试异味
  • mutation-testing - 验证测试有效性

参考资料

评论

支持 Markdown