跳转至

Testing Strategy Analysis

重要性:⭐⭐ 目标读者:测试工程师 关联topics/cache-strategies.md


1. 概览

本文档分析 Claude Code 的测试策略

5 主题: - 测试类型 - 测试框架 - 测试覆盖 - 测试实践 - 改进


2. 5 大测试类型

2.1 单元测试

// 单个函数 / 类
describe('add', () => {
  it('returns sum', () => {
    expect(add(1, 2)).toBe(3)
  })
})

unit

2.2 集成测试

// 多组件协作

integration

2.3 E2E

// 整个流程

e2e

2.4 性能测试

// 测时间

perf

2.5 安全测试

// 攻击场景

security


3. 5 个测试框架(推测)

3.1 Vitest

import { describe, it, expect } from 'vitest'

Vitest(推测)。

3.2 Bun:test

// Bun 内置

Bun:test(推测)。

3.3 MCP Inspector

npx @modelcontextprotocol/inspector /path/to/server.js

Inspector(mcp 测试)。

3.4 React Testing Library

import { render, screen } from '@testing-library/react'

RTL(推测)。

3.5 msw (Mock Service Worker)

// mock HTTP

msw(推测)。


4. 测试覆盖

4.1 已有覆盖

// learn_doc/ 已有 79 测试

79 测试(推测当前)。

4.2 推测目标

类别 目标 实际
单元 80% 推测 60%
集成 50% 推测 30%
E2E 关键流 推测 20%

3 维度


5. 5 个测试实践

5.1 测试位置

src/__tests__/
src/**/__tests__/
src/**.test.ts

co-located

5.2 Mock 策略

// Mock client
const mockClient = {
  call: vi.fn().mockResolvedValue(...)
}

mock

5.3 Snapshot

expect(component).toMatchSnapshot()

snapshot(推测)。

5.4 Coverage

vitest --coverage

coverage(推测)。

5.5 E2E

// 跑整个 CLI
claude -p "test"

e2e


6. 5 个 Bash validator 测试

// bashSecurity.ts
describe('isDangerousRemovalRawPath', () => {
  it('detects rm -rf /', () => {
    expect(isDangerousRemovalRawPath('rm -rf /')).toBe(true)
  })

  it('allows safe paths', () => {
    expect(isDangerousRemovalRawPath('rm -rf /tmp/*')).toBe(false)
  })
})

describe('validateDangerousPatterns', () => {
  it('detects LD_PRELOAD', () => { ... })
  it('detects curl pipe sh', () => { ... })
  it('detects fork bomb', () => { ... })
})

5 测


7. 5 个 ToolUseContext 测试

describe('Read tool', () => {
  it('reads file', async () => {
    const result = await Read(
      { file_path: '/tmp/test.txt' },
      mockContext
    )
    expect(result.content).toContain('test')
  })
})

1 测


8. 5 个 Stream 测试

describe('stream', () => {
  it('emits message_start', async () => {
    const events = []
    for await (const event of client.messages.stream(params)) {
      events.push(event.type)
    }
    expect(events).toContain('message_start')
    expect(events).toContain('content_block_delta')
    expect(events).toContain('message_stop')
  })
})

1 测


9. 5 个常见测试模式

9.1 Arrange-Act-Assert

it('does X', () => {
  // Arrange
  const input = ...
  // Act
  const result = fn(input)
  // Assert
  expect(result).toBe(...)
})

AAA

9.2 Test Fixture

beforeEach(() => {
  // setup
})

fixture

9.3 Parameterized

it.each([
  [1, 2, 3],
  [0, 0, 0],
  [-1, 1, 0],
])('add(%i, %i) = %i', (a, b, expected) => {
  expect(add(a, b)).toBe(expected)
})

parameterized

9.4 Mock Module

vi.mock('./heavy-module', () => ({
  heavy: vi.fn().mockReturnValue(...)
}))

mock

9.5 Async Test

it('async', async () => {
  const result = await asyncFn()
  expect(result).toBe(...)
})

async


10. 5 个 Bash 命令测试

// 1. 简单命令
expect(checkCommand('ls')).toBe('allow')

// 2. 危险命令
expect(checkCommand('rm -rf /')).toBe('deny')

// 3. shell injection
expect(checkCommand('ls; rm -rf /')).toBe('deny')

// 4. LD_PRELOAD
expect(checkCommand('LD_PRELOAD=x ls')).toBe('deny')

// 5. 转义绕过
expect(checkCommand('\\rm -rf /')).toBe('ask')  // 推测

5 测


11. 5 个 Permission 测试

// 1. allow
expect(checkPermission('Bash', { command: 'git status' }, {})).toBe('allow')

// 2. deny
expect(checkPermission('Bash', { command: 'rm -rf /' }, {})).toBe('deny')

// 3. ask
expect(checkPermission('Bash', { command: 'sudo apt install' }, {})).toBe('ask')

// 4. mode
expect(checkPermission('Bash', { command: 'ls' }, { mode: 'bypass' })).toBe('allow')

// 5. classifier
expect(checkPermission('Bash', { command: 'weird_cmd' }, {})).toBe('ask')

5 测


12. 5 个常见反模式

12.1 不写测试

// ❌
// 相信"它能跑就行"

notest

12.2 Mock 一切

// ❌ 测的不是真东西

over-mock

12.3 测试实现

// ❌ 测试内部细节

impl-detail

12.4 慢测试

// ❌ 1 测 1s

slow

12.5 脆测试

// ❌ 改实现就崩

brittle


13. 5 个改进方向

13.1 加 coverage

vitest --coverage

coverage

13.2 加集成

// 多个 module 一起

integration

13.3 加 e2e

// 跑整个 CLI

e2e

13.4 加 fuzz

// fuzz testing

fuzz

13.5 加 property

// property-based testing

property


14. 5 个测试工具

14.1 vitest

vitest run

vitest

14.2 mcp inspector

npx @modelcontextprotocol/inspector server.js

inspector

14.3 c8 (coverage)

c8 vitest run

coverage

14.4 fast-check (property)

import fc from 'fast-check'

fuzz

14.5 nock (HTTP mock)

import nock from 'nock'

HTTP mock


15. 5 个 CI 集成

15.1 GitHub Actions

- run: npm test

CI

15.2 Coverage 报告

- run: vitest --coverage --reporter=lcov
- uses: codecov/codecov-action@v3

coverage report

15.3 多平台

strategy:
  matrix:
    os: [ubuntu, macos, windows]

multi-OS

15.4 Snapshot PR

- uses: actions/upload-artifact
  with: { path: coverage/ }

snapshot

15.5 Required check

# branch protection
required_checks: [test, lint, typecheck]

required


16. 关键 trade-off

覆盖  ↔  速度
真实  ↔  mock
单元  ↔  集成
CI  ↔  本地

4 维


17. 总结

Testing Strategy = 5 类型 + 5 框架

核心: - 5 类型 - 79 现有测试 - 5 反模式 - 5 改进方向

下一步: - 加 coverage - 加 fuzz - 加 property