rlm-tdd

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

RLM TDD Discipline

RLM TDD实施准则

Overview

概述

Test-Driven Development is mandatory for all RLM implementation work. This skill ensures test-first discipline is followed rigorously.
Core Principle: If you didn't watch the test fail, you don't know if it tests the right thing.
The Iron Law for RLM:
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
测试驱动开发(TDD)是所有RLM实施工作的强制要求。本准则确保严格遵循测试优先的规范。
核心原则: 如果你没有看到测试失败,你就无法确定它是否测试了正确的内容。
RLM铁律:
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST

When to Use

适用场景

Always in Phase 3 (Implementation):
  • New features
  • Bug fixes
  • Refactoring
  • Behavior changes
No Exceptions:
  • Not for "simple" changes
  • Not when "under pressure"
  • Not because "tests after achieve same goals"
始终适用于第三阶段(实施阶段):
  • 新功能开发
  • Bug修复
  • 代码重构
  • 行为逻辑变更
无例外情况:
  • 即使是“简单”变更也不例外
  • 即使“时间紧迫”也不例外
  • 不能以“事后写测试能达到同样目的”为借口

RED-GREEN-REFACTOR Cycle

RED-GREEN-REFACTOR 循环

dot
digraph tdd_cycle {
    rankdir=LR;
    red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"];
    verify_red [label="Verify fails\ncorrectly", shape=diamond];
    green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"];
    verify_green [label="Verify passes\nAll green", shape=diamond];
    refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"];
    record [label="Record in\nPhase 3 artifact", shape=box];

    red -> verify_red;
    verify_red -> green [label="yes"];
    verify_red -> red [label="wrong\nfailure"];
    green -> verify_green;
    verify_green -> refactor [label="yes"];
    verify_green -> green [label="no"];
    refactor -> verify_green [label="stay\ngreen"];
    verify_green -> record;
}
dot
digraph tdd_cycle {
    rankdir=LR;
    red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"];
    verify_red [label="Verify fails\ncorrectly", shape=diamond];
    green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"];
    verify_green [label="Verify passes\nAll green", shape=diamond];
    refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"];
    record [label="Record in\nPhase 3 artifact", shape=box];

    red -> verify_red;
    verify_red -> green [label="yes"];
    verify_red -> red [label="wrong\nfailure"];
    green -> verify_green;
    verify_green -> refactor [label="yes"];
    verify_green -> green [label="no"];
    refactor -> verify_green [label="stay\ngreen"];
    verify_green -> record;
}

RED - Write Failing Test

RED - 编写失败的测试

Write one minimal test showing what should happen.
Requirements:
  • One behavior per test
  • Clear, descriptive name
  • Test real code (no mocks unless unavoidable)
  • Clear assertion showing expected outcome
<Good> ```typescript test('rejects empty email with clear error message', async () => { const result = await submitForm({ email: '' }); expect(result.error).toBe('Email is required'); }); ``` </Good> <Bad> ```typescript test('email validation works', async () => { const mock = jest.fn().mockResolvedValue({ valid: true }); const result = await validateEmail(mock); expect(mock).toHaveBeenCalled(); }); ``` </Bad>
编写一个最小化的测试用例,明确预期行为。
要求:
  • 每个测试对应一个独立行为
  • 测试名称清晰、具有描述性
  • 测试真实代码(除非必要,否则不使用mock)
  • 断言明确,展示预期结果
<Good> ```typescript test('rejects empty email with clear error message', async () => { const result = await submitForm({ email: '' }); expect(result.error).toBe('Email is required'); }); ``` </Good> <Bad> ```typescript test('email validation works', async () => { const mock = jest.fn().mockResolvedValue({ valid: true }); const result = await validateEmail(mock); expect(mock).toHaveBeenCalled(); }); ``` </Bad>

Verify RED - Watch It Fail

验证RED阶段 - 确认测试失败

MANDATORY. Never skip.
bash
npm test path/to/test.test.ts
Confirm:
  • Test fails (not errors)
  • Failure message is expected
  • Fails because feature missing (not typos)
Record in Phase 3 artifact:
markdown
undefined
强制要求,绝不能跳过。
bash
npm test path/to/test.test.ts
确认内容:
  • 测试确实失败(而非报错)
  • 失败信息符合预期
  • 失败原因是功能缺失(而非拼写错误)
在第三阶段工件中记录:
markdown
undefined

TDD Cycle for R3 (Email Validation)

R3(邮箱验证)的TDD循环

RED Phase:
  • Test:
    rejects empty email with clear error message
  • Command:
    npm test src/forms/email.test.ts
  • Expected failure: "Email is required" not found
  • Actual failure: [paste output]
  • RED verified: ✅
undefined
RED阶段:
  • 测试用例:
    rejects empty email with clear error message
  • 命令:
    npm test src/forms/email.test.ts
  • 预期失败:未找到"Email is required"
  • 实际失败:[粘贴输出结果]
  • RED阶段验证:✅
undefined

GREEN - Minimal Code

GREEN - 编写最小化代码

Write simplest code to pass the test.
Rules:
  • Just enough to pass
  • No additional features
  • No "while I'm here" improvements
  • No refactoring yet
<Good> ```typescript function submitForm(data: FormData) { if (!data.email?.trim()) { return { error: 'Email is required' }; } // ... rest of form handling } ``` </Good> <Bad> ```typescript function submitForm( data: FormData, options?: { strictMode?: boolean; customValidators?: Validator[]; onValidationError?: (err: Error) => void; } ) { // YAGNI - over-engineered } ``` </Bad>
Record in Phase 3 artifact:
markdown
**GREEN Phase:**
- Implementation: Added null check for email field
- Command: `npm test src/forms/email.test.ts`
- Result: PASS
- GREEN verified: ✅
编写最简单的代码使测试通过。
规则:
  • 仅编写足够通过测试的代码
  • 不添加额外功能
  • 不做“顺便优化”的改进
  • 暂不进行重构
<Good> ```typescript function submitForm(data: FormData) { if (!data.email?.trim()) { return { error: 'Email is required' }; } // ... 其余表单处理逻辑 } ``` </Good> <Bad> ```typescript function submitForm( data: FormData, options?: { strictMode?: boolean; customValidators?: Validator[]; onValidationError?: (err: Error) => void; } ) { // YAGNI - 过度设计 } ``` </Bad>
在第三阶段工件中记录:
markdown
**GREEN阶段:**
- 实现内容:为邮箱字段添加空值检查
- 命令:`npm test src/forms/email.test.ts`
- 结果:通过
- GREEN阶段验证:✅

REFACTOR - Clean Up

REFACTOR - 代码清理

After green only:
  • Remove duplication
  • Improve names
  • Extract helpers
  • Keep tests green
Never add behavior during refactor.
Record in Phase 3 artifact:
markdown
**REFACTOR Phase:**
- Extracted `validateRequired(field, name)` helper
- Renamed `submitForm` to `processFormSubmission` for clarity
- All tests still passing: ✅
仅在GREEN阶段完成后进行:
  • 移除重复代码
  • 优化命名
  • 提取辅助函数
  • 确保所有测试保持通过
重构期间绝不能添加新行为。
在第三阶段工件中记录:
markdown
**REFACTOR阶段:**
- 提取`validateRequired(field, name)`辅助函数
-`submitForm`重命名为`processFormSubmission`以提升清晰度
- 所有测试仍通过:✅

Common Rationalizations (STOP - You're Rationalizing)

常见借口(停止——你在找借口)

ExcuseReality
"This is just a simple fix, no test needed"Simple code breaks. Test takes 30 seconds.
"I'll test after confirming the fix works"Tests passing immediately prove nothing. You never saw it catch the bug.
"Tests after achieve same goals"Tests-after = "what does this do?" Tests-first = "what should this do?"
"I already manually tested it"Ad-hoc ≠ systematic. No record, can't re-run, no regression protection.
"Deleting working code is wasteful"Sunk cost fallacy. Keeping unverified code is technical debt.
"TDD is dogmatic, I'm being pragmatic"TDD IS pragmatic. Finds bugs before commit, enables refactoring.
"I'll keep the code as reference"You'll adapt it. That's testing after. Delete means delete.
"Test hard = design unclear"Listen to the test. Hard to test = hard to use. Simplify design.
"I need to explore first"Fine. Throw away exploration, start TDD fresh.
"This is different because..."It's not. The rules don't have exceptions.
借口实际情况
“这只是个简单修复,不需要测试”简单代码也会出错。编写测试只需30秒。
“我先确认修复有效,之后再写测试”测试立即通过毫无意义,你永远无法确认它是否能捕获bug。
“事后写测试能达到同样目的”事后写测试是“验证代码做了什么”,而先写测试是“定义代码应该做什么”。
“我已经手动测试过了”临时测试≠系统化测试。没有记录,无法重复执行,也无法提供回归保护。
“删除可用代码是浪费”沉没成本谬误。保留未验证的代码就是技术债务。
“TDD太教条,我这是务实”TDD才是务实的做法。它能在提交前发现bug,支持安全重构。
“我要保留代码作为参考”你会修改它的,这本质还是事后测试。删除就意味着彻底删除。
“测试难度大=设计不清晰”倾听测试的反馈。难测试的代码通常也难使用,简化设计即可。
“我需要先探索一下”没问题。探索代码可以丢弃,之后从零开始用TDD实现。
“这个情况不一样,因为……”没有不一样的情况。规则没有例外。

Red Flags - STOP and Start Over

危险信号——停止并重新开始

If you encounter any of these, DELETE CODE and restart with TDD:
  • ❌ Code written before test
  • ❌ Test passes immediately (not testing what you think)
  • ❌ "I'll add tests later"
  • ❌ "This is too simple to test"
  • ❌ "I know what I'm doing, I don't need the ritual"
  • ❌ Can't explain why test failed (or didn't fail)
  • ❌ Test testing mock behavior, not real behavior
  • ❌ Multiple behaviors in one test ("and" in test name)
如果你遇到以下任何情况,删除代码并重新用TDD开始:
  • ❌ 在编写测试前就写了生产代码
  • ❌ 测试立即通过(说明测试没有覆盖你想测的内容)
  • ❌ “我之后再补测试”
  • ❌ “这个太简单了,不需要测试”
  • ❌ “我知道自己在做什么,不需要走流程”
  • ❌ 无法解释测试为什么失败(或为什么没失败)
  • ❌ 测试的是mock行为,而非真实行为
  • ❌ 一个测试包含多个行为(测试名称中有“和”)

Integration with RLM Phase 3

与RLM第三阶段的集成

Phase 3 Artifact TDD Section

第三阶段工件中的TDD部分

Every Phase 3 artifact must include:
markdown
undefined
每个第三阶段工件必须包含:
markdown
undefined

TDD Compliance Log

TDD合规日志

Requirement R1 (Feature X)

需求R1(功能X)

Test:
test/features/x.test.ts
- "should do Y when Z"
  • RED: [timestamp] - Failed as expected: [output]
  • GREEN: [timestamp] - Minimal implementation: [description]
  • REFACTOR: [timestamp] - Cleanups: [description]
  • Final state: ✅ All tests passing
测试用例:
test/features/x.test.ts
- “当Z发生时应该执行Y”
  • RED阶段:[时间戳] - 如预期失败:[输出结果]
  • GREEN阶段:[时间戳] - 最小化实现:[描述]
  • REFACTOR阶段:[时间戳] - 清理内容:[描述]
  • 最终状态:✅ 所有测试通过

Requirement R2 (Bug Fix)

需求R2(Bug修复)

Regression Test:
test/bugs/issue-123.test.ts
- "reproduces crash on empty input"
  • RED: [timestamp] - Confirmed bug: [output]
  • GREEN: [timestamp] - Fix applied: [description]
  • REFACTOR: [timestamp] - N/A (minimal fix)
  • Final state: ✅ Test passes, bug fixed
undefined
回归测试:
test/bugs/issue-123.test.ts
- “复现空输入导致的崩溃”
  • RED阶段:[时间戳] - 确认bug:[输出结果]
  • GREEN阶段:[时间戳] - 修复实现:[描述]
  • REFACTOR阶段:[时间戳] - 不适用(最小化修复)
  • 最终状态:✅ 测试通过,bug已修复
undefined

Phase 3 Coverage Gate Addition

第三阶段的覆盖率检查项

markdown
undefined
markdown
undefined

Coverage Gate

覆盖率检查

  • Every new function has a corresponding test
  • Every bug fix has a regression test that fails before fix
  • All RED phases documented with failure output
  • All GREEN phases documented with minimal implementation
  • All tests passing (no skipped tests)
  • No production code written before failing test
TDD Compliance: PASS / FAIL
undefined
  • 每个新函数都有对应的测试
  • 每个Bug修复都有对应的回归测试,且修复前测试失败
  • 所有RED阶段都记录了失败输出
  • 所有GREEN阶段都记录了最小化实现
  • 所有测试通过(无跳过的测试)
  • 没有在失败测试前编写生产代码
TDD合规性:通过 / 不通过
undefined

Phase 3 Approval Gate Addition

第三阶段的审批检查项

markdown
undefined
markdown
undefined

Approval Gate

审批检查

  • TDD Compliance: PASS
  • Implementation matches Phase 3 plan
  • No code without preceding failing test
  • All tests documented in TDD Compliance Log
Approval: PASS / FAIL
undefined
  • TDD合规性:通过
  • 实现内容与第三阶段计划一致
  • 没有无前置失败测试的生产代码
  • 所有测试都在TDD合规日志中记录
审批结果:通过 / 不通过
undefined

Bug Fix TDD Procedure

Bug修复的TDD流程

  1. Add Regression Test First
    • Write test that reproduces the bug
    • Run test, confirm it fails with expected error
    • Document failure in Phase 3 artifact
  2. Implement Minimal Fix
    • Fix only what's needed to make test pass
    • Run test, confirm it passes
    • Document fix in Phase 3 artifact
  3. Verify No Regressions
    • Run full test suite
    • Confirm nothing else broke
    • Document in Phase 3 artifact
  4. Lock Phase 3
    • TDD Compliance: PASS
    • Approval: PASS
    • Status: LOCKED
  1. 先添加回归测试
    • 编写能复现bug的测试用例
    • 运行测试,确认测试因预期错误而失败
    • 在第三阶段工件中记录失败情况
  2. 实现最小化修复
    • 仅修复使测试通过所需的内容
    • 运行测试,确认测试通过
    • 在第三阶段工件中记录修复内容
  3. 验证无回归问题
    • 运行完整测试套件
    • 确认没有其他功能被破坏
    • 在第三阶段工件中记录验证结果
  4. 锁定第三阶段
    • TDD合规性:通过
    • 审批:通过
    • 状态:已锁定

Example: Complete Phase 3 TDD Section

示例:完整的第三阶段TDD部分

markdown
undefined
markdown
undefined

TDD Compliance Log

TDD合规日志

R1: Add email validation

R1:添加邮箱验证

Test:
test/forms/validation.test.ts
RED Phase (2026-02-21T10:15:00Z):
bash
$ npm test test/forms/validation.test.ts
FAIL: Expected 'Email is required', got undefined
RED verified: ✅
GREEN Phase (2026-02-21T10:18:00Z):
  • Added null check in
    submitForm()
    function
  • Test passes GREEN verified: ✅
REFACTOR Phase (2026-02-21T10:22:00Z):
  • Extracted
    validateRequired()
    helper
  • All tests still passing REFACTOR complete: ✅
测试用例:
test/forms/validation.test.ts
RED阶段(2026-02-21T10:15:00Z):
bash
$ npm test test/forms/validation.test.ts
失败:预期为'Email is required',实际得到undefined
RED阶段验证:✅
GREEN阶段(2026-02-21T10:18:00Z):
  • submitForm()
    函数中添加了空值检查
  • 测试通过 GREEN阶段验证:✅
REFACTOR阶段(2026-02-21T10:22:00Z):
  • 提取了
    validateRequired()
    辅助函数
  • 所有测试仍通过 REFACTOR阶段完成:✅

R2: Fix crash on empty array

R2:修复空数组导致的崩溃

Regression Test:
test/utils/array.test.ts
RED Phase (2026-02-21T10:25:00Z):
bash
$ npm test test/utils/array.test.ts
FAIL: TypeError: Cannot read property 'map' of undefined
RED verified: Bug reproduced ✅
GREEN Phase (2026-02-21T10:27:00Z):
  • Added guard clause in
    processItems()
  • Test passes GREEN verified: ✅
REFACTOR: N/A (minimal 2-line fix)
回归测试:
test/utils/array.test.ts
RED阶段(2026-02-21T10:25:00Z):
bash
$ npm test test/utils/array.test.ts
失败:TypeError: Cannot read property 'map' of undefined
RED阶段验证:Bug已复现 ✅
GREEN阶段(2026-02-21T10:27:00Z):
  • processItems()
    中添加了守卫语句
  • 测试通过 GREEN阶段验证:✅
REFACTOR阶段:不适用(仅两行的最小化修复)

Verification

验证

Full suite run:
npm test
Result: 47 passing, 0 failing
undefined
完整套件运行命令:
npm test
结果:47个通过,0个失败
undefined

References

参考资料

  • REQUIRED: Follow this skill for all Phase 3 implementation work
  • SEE ALSO:
    references/rationalizations.md
    for extended excuse/reality table
  • 强制要求: 所有第三阶段的实施工作必须遵循本准则
  • 另请参阅:
    references/rationalizations.md
    以获取扩展的借口/实际情况对照表