quality-unit-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Quality Unit Testing for Rust

Rust高质量单元测试

Write tests that catch real bugs and provide deployment confidence.
编写能够发现真实Bug并为部署提供信心的测试。

Core Principles

核心原则

Quality over coverage: Tests should catch real bugs, not just boost percentages.
质量优先于覆盖率:测试应能发现真实的Bug,而非仅仅提高覆盖率数值。

Quick Reference

快速参考

Naming:
test_<function>_<scenario>_<expected>

命名规范:
test_<function>_<scenario>_<expected>

rust
#[test]
fn test_process_payment_insufficient_funds_returns_error()

#[tokio::test]
async fn test_withdraw_valid_amount_decreases_balance()
rust
#[test]
fn test_process_payment_insufficient_funds_returns_error()

#[tokio::test]
async fn test_withdraw_valid_amount_decreases_balance()

AAA Pattern (Arrange-Act-Assert)

AAA模式(Arrange-Act-Assert)

rust
#[test]
fn test_account_withdraw_decreases_balance() {
    // Arrange
    let mut account = Account::new(100);

    // Act
    let result = account.withdraw(30);

    // Assert
    assert!(result.is_ok());
    assert_eq!(account.balance(), 70);
}
rust
#[test]
fn test_account_withdraw_decreases_balance() {
    // Arrange
    let mut account = Account::new(100);

    // Act
    let result = account.withdraw(30);

    // Assert
    assert!(result.is_ok());
    assert_eq!(account.balance(), 70);
}

Isolation

测试隔离

✓ Mock: APIs, databases, file systems, external services ✗ Don't mock: Value types, pure functions, code under test
✓ 模拟:API、数据库、文件系统、外部服务 ✗ 无需模拟:值类型、纯函数、被测代码

Single Responsibility

单一职责

Each test verifies ONE behavior with ONE reason to fail.
每个测试仅验证一种行为,且只有一个失败原因。

Rust-Specific Patterns

Rust特定模式

rust
// Async tests
#[tokio::test]
async fn test_async_operation() { /* ... */ }

// Result-based tests
#[test]
fn test_operation() -> anyhow::Result<()> { /* ... */ }

// Test builders
let episode = TestEpisodeBuilder::new()
    .with_task("Test task")
    .completed(true)
    .build();

// RAII cleanup
struct TestDb(TempDir);
impl Drop for TestDb { fn drop(&mut self) { /* auto cleanup */ } }
rust
// Async tests
#[tokio::test]
async fn test_async_operation() { /* ... */ }

// Result-based tests
#[test]
fn test_operation() -> anyhow::Result<()> { /* ... */ }

// Test builders
let episode = TestEpisodeBuilder::new()
    .with_task("Test task")
    .completed(true)
    .build();

// RAII cleanup
struct TestDb(TempDir);
impl Drop for TestDb { fn drop(&mut self) { /* auto cleanup */ } }

Success Metrics

成功指标

✓ Deploy without manual testing ✓ Test failures pinpoint exact problems ✓ Refactoring doesn't break unrelated tests ✓ Tests run in milliseconds
✓ 无需手动测试即可部署 ✓ 测试失败能精准定位问题 ✓ 重构不会破坏无关测试 ✓ 测试运行耗时以毫秒计

Workflow

工作流程

Creating Tests:
  1. Understand the code behavior
  2. Identify risks
  3. Write failing test first (red-green-refactor)
  4. Apply AAA pattern
  5. Isolate dependencies
  6. Verify speed (milliseconds)
Reviewing Tests:
  1. Run analysis script
  2. Check naming conventions
  3. Ensure isolation
  4. Confirm single responsibility
创建测试:
  1. 理解代码行为
  2. 识别风险
  3. 先编写失败的测试(红-绿-重构)
  4. 应用AAA模式
  5. 隔离依赖
  6. 验证速度(毫秒级)
评审测试:
  1. 运行分析脚本
  2. 检查命名规范
  3. 确保测试隔离
  4. 确认单一职责