tdd-workflow

强制要求:所有新功能、Bug 修复、重构必须达到 80% 以上测试覆盖率。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tdd-workflow" with this command: npx skills add cacr92/wereply/cacr92-wereply-tdd-workflow

TDD 工作流 Skill

核心原则

强制要求:所有新功能、Bug 修复、重构必须达到 80% 以上测试覆盖率。

RED-GREEN-REFACTOR 循环

  1. RED(写测试,测试失败)

先写测试,验证测试会失败(因为功能尚未实现)。

  1. GREEN(实现代码,测试通过)

编写最小代码使测试通过。

  1. REFACTOR(重构代码,保持测试通过)

优化代码,保持所有测试通过。

工作流程

步骤 1:编写用户故事

作为用户,我希望能够创建新的饲料配方。

验收标准:

  • 配方名称必填,长度 2-50 个字符
  • 品种代码必填,必须是有效的品种
  • 创建成功后返回配方 ID

步骤 2:生成测试用例

Rust 测试:

#[tokio::test] async fn test_create_formula_success() { }

#[tokio::test] async fn test_create_formula_empty_name() { }

#[tokio::test] async fn test_create_formula_name_too_long() { }

#[tokio::test] async fn test_create_formula_invalid_species() { }

TypeScript 测试:

describe('FormulaForm', () => { it('should create formula successfully', async () => { }); it('should show error when name is empty', async () => { }); it('should show error when name is too long', async () => { }); });

步骤 3:运行测试(RED)

cargo test # Rust npm test # TypeScript

预期结果:测试失败。

步骤 4:实现代码(GREEN)

pub async fn create_formula(&self, dto: CreateFormulaDto) -> Result<i64> { if dto.name.is_empty() { return Err(anyhow!("配方名称不能为空")); }

let formula_id = sqlx::query!(
    "INSERT INTO formulas (name, species_code) VALUES (?, ?)",
    dto.name, dto.species_code
)
.execute(&#x26;self.pool)
.await?
.last_insert_rowid();

Ok(formula_id)

}

步骤 5:再次运行测试

cargo test npm test

预期结果:所有测试通过。

步骤 6:重构(REFACTOR)

// 提取验证逻辑 fn validate_formula_name(name: &str) -> Result<()> { if name.is_empty() { return Err(anyhow!("配方名称不能为空")); } Ok(()) }

pub async fn create_formula(&self, dto: CreateFormulaDto) -> Result<i64> { validate_formula_name(&dto.name)?; // ... }

步骤 7:验证覆盖率

cargo tarpaulin --out Html # Rust npm run test:coverage # TypeScript

要求:覆盖率 >= 80%。

测试类型

  1. 单元测试

#[test] fn test_validate_formula_name() { assert!(validate_formula_name("测试配方").is_ok()); assert!(validate_formula_name("").is_err()); }

  1. 集成测试

#[tokio::test] async fn test_create_formula_integration() { let pool = setup_test_db().await; let repo = FormulaRepository::new(Arc::new(pool));

let dto = CreateFormulaDto {
    name: "测试配方".to_string(),
    species_code: "PIG".to_string(),
};

let result = repo.create(dto).await;
assert!(result.is_ok());

cleanup_test_db().await;

}

Mock 示例

Mock Tauri 命令(TypeScript)

import { vi } from 'vitest';

vi.mock('../bindings', () => ({ commands: { createFormula: vi.fn(), }, }));

it('should create formula', async () => { vi.mocked(commands.createFormula).mockResolvedValue({ success: true, data: { id: 1 }, });

const result = await createFormula(dto); expect(result.success).toBe(true); });

Mock 数据库(Rust)

use mockall::mock;

mock! { pub FormulaRepository { async fn create(&self, dto: CreateFormulaDto) -> Result<i64>; } }

#[tokio::test] async fn test_with_mock() { let mut mock_repo = MockFormulaRepository::new(); mock_repo.expect_create().returning(|_| Ok(1));

let service = FormulaService::new(Arc::new(mock_repo));
let result = service.create_formula(dto).await;

assert!(result.is_ok());

}

最佳实践

  • 测试用户行为而非实现 → 测试"点击提交后显示成功消息"

  • 保持测试快速 → 单元测试 < 100ms

  • Mock 外部依赖 → Mock 数据库、API、文件系统

  • 测试隔离 → 每个测试独立运行

  • 测试错误路径 → 测试正常和错误情况

  • 描述性测试名称 → test_validate_formula_name_rejects_empty_string

提交前检查清单

  • 所有测试通过

  • 覆盖率 >= 80%

  • 无跳过的测试

  • 测试命名清晰

  • 边界情况已测试

  • 错误路径已测试

  • Mock 使用合理

  • 测试独立运行

常见陷阱

  • 测试实现细节 → 应测试用户可见的行为

  • 测试之间有依赖 → 每个测试独立设置数据

  • 过度 Mock → 只 Mock 外部依赖

  • 忽略异步问题 → 正确处理所有异步操作

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

wechat-automation

No summary provided by upstream source.

Repository SourceNeeds Review
139-cacr92
General

pdf

No summary provided by upstream source.

Repository SourceNeeds Review
General

ipc-communication

No summary provided by upstream source.

Repository SourceNeeds Review
General

docx

No summary provided by upstream source.

Repository SourceNeeds Review