tdd-workflows-tdd-red

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Write comprehensive failing tests following TDD red phase principles.
[Extended thinking: Generates failing tests that properly define expected behavior using test-automator agent.]
遵循TDD红阶段原则编写全面的失败测试。
[拓展思考:利用test-automator Agent生成能准确定义预期行为的失败测试。]

Use this skill when

适用场景

  • Starting the TDD red phase for new behavior
  • You need failing tests that capture expected behavior
  • You want edge case coverage before implementation
  • 为新功能启动TDD红阶段时
  • 需要能体现预期行为的失败测试时
  • 希望在实现前覆盖边缘情况时

Do not use this skill when

不适用场景

  • You are in the green or refactor phase
  • You only need performance benchmarks
  • Tests must run against production systems
  • 处于TDD绿阶段或重构阶段时
  • 仅需要性能基准测试时
  • 测试必须在生产环境运行时

Instructions

操作步骤

  1. Identify behaviors, constraints, and edge cases.
  2. Generate failing tests that define expected outcomes.
  3. Ensure failures are due to missing behavior, not setup errors.
  4. Document how to run tests and verify failures.
  1. 识别功能行为、约束条件和边缘情况。
  2. 生成能定义预期结果的失败测试。
  3. 确保测试失败是因为功能未实现,而非配置错误。
  4. 记录如何运行测试并验证失败结果。

Safety

注意事项

  • Keep test data isolated and avoid production environments.
  • Avoid flaky external dependencies in the red phase.
  • 保持测试数据隔离,避免涉及生产环境。
  • 在红阶段避免依赖不稳定的外部服务。

Role

角色定位

Generate failing tests using Task tool with subagent_type="unit-testing::test-automator".
使用Task工具,指定subagent_type="unit-testing::test-automator"来生成失败测试。

Prompt Template

提示词模板

"Generate comprehensive FAILING tests for: $ARGUMENTS
"为以下内容生成全面的失败测试:$ARGUMENTS

Core Requirements

核心要求

  1. Test Structure
    • Framework-appropriate setup (Jest/pytest/JUnit/Go/RSpec)
    • Arrange-Act-Assert pattern
    • should_X_when_Y naming convention
    • Isolated fixtures with no interdependencies
  2. Behavior Coverage
    • Happy path scenarios
    • Edge cases (empty, null, boundary values)
    • Error handling and exceptions
    • Concurrent access (if applicable)
  3. Failure Verification
    • Tests MUST fail when run
    • Failures for RIGHT reasons (not syntax/import errors)
    • Meaningful diagnostic error messages
    • No cascading failures
  4. Test Categories
    • Unit: Isolated component behavior
    • Integration: Component interaction
    • Contract: API/interface contracts
    • Property: Mathematical invariants
  1. 测试结构
    • 适配对应测试框架的配置(Jest/pytest/JUnit/Go/RSpec)
    • 遵循Arrange-Act-Assert模式
    • 使用should_X_when_Y的命名规范
    • 独立的测试夹具,无相互依赖
  2. 行为覆盖
    • 正常流程场景
    • 边缘情况(空值、Null、边界值)
    • 错误处理与异常场景
    • 并发访问(如适用)
  3. 失败验证
    • 测试运行时必须失败
    • 失败原因正确(非语法/导入错误)
    • 有意义的诊断错误信息
    • 无连锁失败
  4. 测试分类
    • 单元测试:独立组件的行为
    • 集成测试:组件间的交互
    • 契约测试:API/接口契约
    • 属性测试:数学不变量验证

Framework Patterns

框架模式

JavaScript/TypeScript (Jest/Vitest)
  • Mock dependencies with
    vi.fn()
    or
    jest.fn()
  • Use
    @testing-library
    for React components
  • Property tests with
    fast-check
Python (pytest)
  • Fixtures with appropriate scopes
  • Parametrize for multiple test cases
  • Hypothesis for property-based tests
Go
  • Table-driven tests with subtests
  • t.Parallel()
    for parallel execution
  • Use
    testify/assert
    for cleaner assertions
Ruby (RSpec)
  • let
    for lazy loading,
    let!
    for eager
  • Contexts for different scenarios
  • Shared examples for common behavior
JavaScript/TypeScript (Jest/Vitest)
  • 使用
    vi.fn()
    jest.fn()
    模拟依赖
  • 针对React组件使用
    @testing-library
  • 使用
    fast-check
    进行属性测试
Python (pytest)
  • 使用对应作用域的测试夹具(fixtures)
  • 用参数化实现多测试用例
  • 使用Hypothesis进行属性测试
Go
  • 采用表格驱动测试与子测试
  • 使用
    t.Parallel()
    实现并行执行
  • testify/assert
    简化断言
Ruby (RSpec)
  • let
    用于延迟加载,
    let!
    用于立即加载
  • 用Context区分不同场景
  • 共享示例实现通用行为复用

Quality Checklist

质量检查清单

  • Readable test names documenting intent
  • One behavior per test
  • No implementation leakage
  • Meaningful test data (not 'foo'/'bar')
  • Tests serve as living documentation
  • 测试名称清晰易懂,能体现测试意图
  • 每个测试仅验证一个行为
  • 不泄露实现细节
  • 使用有意义的测试数据(而非'foo'/'bar'这类占位符)
  • 测试可作为活文档

Anti-Patterns to Avoid

需避免的反模式

  • Tests passing immediately
  • Testing implementation vs behavior
  • Complex setup code
  • Multiple responsibilities per test
  • Brittle tests tied to specifics
  • 测试立即通过
  • 测试实现细节而非功能行为
  • 复杂的配置代码
  • 单个测试承担多个职责
  • 与具体实现强耦合的脆弱测试

Edge Case Categories

边缘情况分类

  • Null/Empty: undefined, null, empty string/array/object
  • Boundaries: min/max values, single element, capacity limits
  • Special Cases: Unicode, whitespace, special characters
  • State: Invalid transitions, concurrent modifications
  • Errors: Network failures, timeouts, permissions
  • 空值/空对象:undefined、null、空字符串/数组/对象
  • 边界值:最小/最大值、单元素、容量限制
  • 特殊场景:Unicode字符、空白字符、特殊符号
  • 状态相关:无效状态转换、并发修改
  • 错误场景:网络故障、超时、权限问题

Output Requirements

输出要求

  • Complete test files with imports
  • Documentation of test purpose
  • Commands to run and verify failures
  • Metrics: test count, coverage areas
  • Next steps for green phase"
  • 包含导入语句的完整测试文件
  • 测试目的说明文档
  • 运行测试并验证失败的命令
  • 指标:测试数量、覆盖范围
  • 绿阶段的后续步骤"

Validation

验证步骤

After generation:
  1. Run tests - confirm they fail
  2. Verify helpful failure messages
  3. Check test independence
  4. Ensure comprehensive coverage
生成测试后:
  1. 运行测试 - 确认测试失败
  2. 验证错误信息是否有帮助
  3. 检查测试是否相互独立
  4. 确保覆盖全面

Example (Minimal)

示例(极简版)

typescript
// auth.service.test.ts
describe('AuthService', () => {
  let authService: AuthService;
  let mockUserRepo: jest.Mocked<UserRepository>;

  beforeEach(() => {
    mockUserRepo = { findByEmail: jest.fn() } as any;
    authService = new AuthService(mockUserRepo);
  });

  it('should_return_token_when_valid_credentials', async () => {
    const user = { id: '1', email: 'test@example.com', passwordHash: 'hashed' };
    mockUserRepo.findByEmail.mockResolvedValue(user);

    const result = await authService.authenticate('test@example.com', 'pass');

    expect(result.success).toBe(true);
    expect(result.token).toBeDefined();
  });

  it('should_fail_when_user_not_found', async () => {
    mockUserRepo.findByEmail.mockResolvedValue(null);

    const result = await authService.authenticate('none@example.com', 'pass');

    expect(result.success).toBe(false);
    expect(result.error).toBe('INVALID_CREDENTIALS');
  });
});
Test requirements: $ARGUMENTS
typescript
// auth.service.test.ts
describe('AuthService', () => {
  let authService: AuthService;
  let mockUserRepo: jest.Mocked<UserRepository>;

  beforeEach(() => {
    mockUserRepo = { findByEmail: jest.fn() } as any;
    authService = new AuthService(mockUserRepo);
  });

  it('should_return_token_when_valid_credentials', async () => {
    const user = { id: '1', email: 'test@example.com', passwordHash: 'hashed' };
    mockUserRepo.findByEmail.mockResolvedValue(user);

    const result = await authService.authenticate('test@example.com', 'pass');

    expect(result.success).toBe(true);
    expect(result.token).toBeDefined();
  });

  it('should_fail_when_user_not_found', async () => {
    mockUserRepo.findByEmail.mockResolvedValue(null);

    const result = await authService.authenticate('none@example.com', 'pass');

    expect(result.success).toBe(false);
    expect(result.error).toBe('INVALID_CREDENTIALS');
  });
});
测试需求:$ARGUMENTS