property-test-generator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Property-Based Test Generator

基于属性的测试生成器

Design and generate property-based tests for changed files, with self-scoring to ensure quality (24/30+ on the evaluation rubric).
为已修改文件设计并生成基于属性的测试,通过自我评分确保测试质量(评估标准得分≥24/30)。

Constraints

约束条件

  • Black-box only — never depend on internal implementation details.
  • No trivial properties (type-check-only, no-exception-only are forbidden).
  • Minimize
    assume
    /
    filter
    — express constraints in generators instead.
  • Always ensure seed + minimal counterexample reproducibility.
  • 仅黑盒测试——绝不依赖内部实现细节。
  • 禁止无意义属性(仅类型检查、仅无异常的属性不被允许)。
  • 尽量减少
    assume
    /
    filter
    的使用——在生成器中表达约束条件。
  • 始终确保种子值+最小化反例的可复现性。

Workflow

工作流程

  1. Detect changed files — identify PBT candidates from git diff
  2. Extract specifications — read each file, document inputs/outputs/constraints
  3. Design properties — minimum 5 per function, following the property type hierarchy
  4. Build generators — express input domains with edge cases and good shrinking
  5. Implement tests — write test files in the project's framework
  6. Self-score — evaluate against rubric, improve if below 24/30
  7. Report — present results to user
  1. 检测已修改文件——从git diff中识别PBT候选文件
  2. 提取规格说明——读取每个文件,记录输入/输出/约束条件
  3. 设计属性——每个函数至少设计5个属性,遵循属性类型层级
  4. 构建生成器——设计包含边缘案例和良好收缩能力的输入域生成策略
  5. 实现测试——按照项目框架编写测试文件
  6. 自我评分——根据评估标准打分,若得分低于24/30则进行优化
  7. 生成报告——向用户展示结果

Step 1 — Detect Changed Files

步骤1——检测已修改文件

Identify PBT candidates from the current branch diff:
bash
git diff --name-only --diff-filter=ACMR $(git merge-base main HEAD) HEAD
Filter to source files (
.ts
,
.tsx
,
.js
,
.jsx
,
.py
,
.rs
), excluding test files, config, styles, and assets.
Good PBT candidates (prioritize these):
  • Pure functions (no side effects, deterministic)
  • Validators / type guards (
    is*
    ,
    validate*
    )
  • Parsers / serializers (encode/decode, parse/stringify)
  • Formatters (data → string transformations)
  • Reducers / state transitions
  • Sorting / filtering / transformation utilities
Poor PBT candidates (skip these):
  • React components (use integration tests instead)
  • Side-effectful functions (API calls, file I/O)
  • Simple getters/setters with no logic
从当前分支的diff中识别PBT候选文件:
bash
git diff --name-only --diff-filter=ACMR $(git merge-base main HEAD) HEAD
筛选源文件(
.ts
,
.tsx
,
.js
,
.jsx
,
.py
,
.rs
),排除测试文件、配置文件、样式文件和资源文件。
优质PBT候选对象(优先处理):
  • 纯函数(无副作用、确定性)
  • 验证器/类型守卫(
    is*
    ,
    validate*
  • 解析器/序列化器(编码/解码、解析/字符串化)
  • 格式化工具(数据→字符串转换)
  • 归约器/状态转换函数
  • 排序/过滤/转换工具函数
劣质PBT候选对象(跳过):
  • React组件(改用集成测试)
  • 有副作用的函数(API调用、文件I/O)
  • 无逻辑的简单getter/setter

Step 2 — Extract Specifications

步骤2——提取规格说明

For each candidate function, document:
  1. Inputs — types, ranges, constraints
  2. Outputs — types, expected relationships to inputs
  3. State — mutable state involved, if any
  4. Requirements — business rules as bullet points
  5. Preconditions — what must be true about inputs
针对每个候选函数,记录以下内容:
  1. 输入——类型、范围、约束条件
  2. 输出——类型、与输入的预期关系
  3. 状态——涉及的可变状态(若有)
  4. 需求——以要点形式记录业务规则
  5. 前置条件——输入必须满足的条件

Step 3 — Design Properties (min 5)

步骤3——设计属性(至少5个)

Design properties in this priority order:
TypeDescriptionWhen to use
InvariantOutput always satisfies a conditionLength preservation, range bounds, type guarantees
Round-trip
decode(encode(x)) === x
Parsers, serializers, codecs
Idempotence
f(f(x)) === f(x)
Normalizers, formatters, canonicalizers
MetamorphicRelationship between
f(x)
and
f(transform(x))
Sort, filter, math operations
Monotonicity
x ≤ y → f(x) ≤ f(y)
Scoring, ranking, pricing
Reference model
optimized(x) === naive(x)
Optimized reimplementations
Each property MUST include:
  • Natural-language description
  • Corresponding requirement from Step 2
  • One buggy implementation example that this property would catch
按以下优先级设计属性:
类型描述适用场景
不变性输出始终满足某个条件长度保留、范围边界、类型保证
往返一致性
decode(encode(x)) === x
解析器、序列化器、编解码器
幂等性
f(f(x)) === f(x)
归一化工具、格式化工具、规范化工具
变形性
f(x)
f(transform(x))
之间的关系
排序、过滤、数学运算
单调性
x ≤ y → f(x) ≤ f(y)
评分、排名、定价
参考模型
optimized(x) === naive(x)
优化后的重实现
每个属性必须包含:
  • 自然语言描述
  • 与步骤2中需求的对应关系
  • 该属性能够发现的错误实现示例

Step 4 — Build Generators

步骤4——构建生成器

Determine the project language and select the library:
  • TypeScript/JavaScript → fast-check — see references/fast-check.md
  • Python → hypothesis — see references/hypothesis.md
  • Rust → proptest — see references/proptest.md
Generator design rules:
  • Express constraints via generator composition, not
    filter
    /
    assume
    .
  • Target filter rejection rate < 10%.
  • Explicitly include edge cases: empty, zero, boundary, max-size, duplicates, skewed distributions.
  • Prefer base Arbitrary/Strategy combinations for natural shrinking.
  • Set explicit size limits to control generation cost.
确定项目语言并选择对应库:
  • TypeScript/JavaScript → fast-check — 参考references/fast-check.md
  • Python → hypothesis — 参考references/hypothesis.md
  • Rust → proptest — 参考references/proptest.md
生成器设计规则:
  • 通过生成器组合表达约束,而非
    filter
    /
    assume
  • 目标过滤拒绝率<10%。
  • 明确包含边缘案例:空值、零值、边界值、最大尺寸、重复值、偏态分布。
  • 优先使用基础Arbitrary/Strategy组合以实现自然收缩。
  • 设置明确的大小限制以控制生成成本。

Step 5 — Implement Tests

步骤5——实现测试

Write test files following project conventions:
  • Read existing
    *.property.test.*
    files for style reference.
  • Read test config and setup files.
  • File naming:
    *.property.test.ts
    (TS/JS),
    test_*_property.py
    (Python), or
    #[cfg(test)] mod tests
    /
    tests/
    (Rust). Follow project convention.
Each test must include:
  1. Descriptive property name
  2. Generator definition
  3. Test body (arrange/act/assert)
  4. Seed output on failure
  5. Reproduction instructions (as comment)
遵循项目规范编写测试文件:
  • 参考现有
    *.property.test.*
    文件的风格。
  • 阅读测试配置和初始化文件。
  • 文件命名:
    *.property.test.ts
    (TS/JS)、
    test_*_property.py
    (Python)或
    #[cfg(test)] mod tests
    /
    tests/
    (Rust)。遵循项目约定。
每个测试必须包含:
  1. 描述性的属性名称
  2. 生成器定义
  3. 测试主体(准备/执行/断言)
  4. 失败时的种子输出
  5. 复现步骤(作为注释)

Step 6 — Self-Score

步骤6——自我评分

After implementation, evaluate against the rubric in references/evaluation.md.
Score 15 criteria (A1-A5, B1-B6, C1-C4) at 0-2 points each.
  • 24+ points: proceed to report.
  • < 24 points: identify weak criteria, improve properties/generators/diagnostics, re-score. Repeat up to 2 times.
实现完成后,根据references/evaluation.md中的评估标准进行打分。
对15项标准(A1-A5、B1-B6、C1-C4)分别打分,每项0-2分。
  • ≥24分:进入报告环节。
  • <24分:识别薄弱项,优化属性/生成器/诊断信息,重新打分。最多重复2次。

Step 7 — Report

步骤7——生成报告

Output in this order:
  1. Requirements summary — extracted specifications
  2. Property list — natural language + requirement mapping + buggy impl example
  3. Generator strategies — with edge case rationale
  4. Test implementation — actual test code (not pseudocode)
  5. Reproduction instructions — how to re-run with seed
  6. Score table + improvement log — final self-assessment
按以下顺序输出:
  1. 需求摘要——提取的规格说明
  2. 属性列表——自然语言描述+需求映射+错误实现示例
  3. 生成器策略——包含边缘案例的设计理由
  4. 测试实现代码——实际测试代码(非伪代码)
  5. 复现说明——如何使用种子值重新运行测试
  6. 得分表+优化日志——最终自我评估结果