AGENT SKILL

test-strategy-design

Test pyramid strategy, test design patterns, coverage analysis, and quality gate configuration. Use when designing test strategies, improving coverage, setting up automation, or defining quality gates. Covers unit, integration, and E2E testing across frameworks.

License 许可
MIT
最近更新
2026-11-01
Stars
★ 3
Forks
1

01 前言 Front Matter

name
test-strategy-design
description
Test pyramid strategy, test design patterns, coverage analysis, and quality gate configuration. Use when designing test strategies, improving coverage, setting up automation, or defining quality gates. Covers unit, integration, and E2E testing across frameworks.

03 SKILL.md 正文

Test Strategy Design

Systematic patterns for designing comprehensive test strategies that balance coverage, speed, and maintainability.

When to Activate

  • Designing test strategy for new projects
  • Improving existing test coverage
  • Setting up test automation frameworks
  • Configuring CI/CD quality gates
  • Analyzing test gaps and priorities
  • Establishing testing standards for teams

The Test Pyramid

The test pyramid guides the distribution of testing effort:

                 ┌─────────┐
                 │   E2E   │  ~10% - Critical user journeys
                 │ Tests   │  Slow, expensive, high confidence
                 ├─────────┤
                 │ Integr- │  ~20% - Component interactions
                 │  ation  │  Medium speed, real dependencies
                 ├─────────┤
                 │  Unit   │  ~70% - Business logic
                 │  Tests  │  Fast, isolated, cheap
                 └─────────┘

Layer Characteristics

Layer Speed Isolation Confidence Maintenance
Unit < 10ms Complete Low per test Low
Integration < 1s Partial Medium Medium
E2E < 30s None High High

When to Test at Each Layer

Unit Tests - Test here when:

  • Pure business logic
  • Algorithmic code
  • Data transformations
  • Validation rules
  • Edge cases and boundaries

Integration Tests - Test here when:

  • Database interactions
  • API contracts
  • Service communication
  • File system operations
  • Cache behavior

E2E Tests - Test here when:

  • Critical user journeys
  • Cross-system workflows
  • Authentication flows
  • Payment processes
  • Smoke tests for deployments

Test Design Patterns

Unit Test Patterns

Arrange-Act-Assert (AAA)

// Arrange: Set up test data and dependencies
const user = createUser({ email: 'test@example.com' });
const validator = new EmailValidator();

// Act: Execute the behavior under test
const result = validator.validate(user.email);

// Assert: Verify the expected outcome
expect(result.isValid).toBe(true);

One Assertion Per Test

Focus each test on a single behavior:

// Bad: Multiple unrelated assertions
test('user validation', () => {
  expect(user.isValid()).toBe(true);
  expect(user.email).toContain('@');
  expect(user.createdAt).toBeDefined();
});

// Good: Separate tests for each behavior
test('validates user with proper email', () => {
  expect(user.isValid()).toBe(true);
});

test('email contains @ symbol', () => {
  expect(user.email).toContain('@');
});

Descriptive Test Names

Test names should describe the expected behavior:

// Bad
test('email test', () => { ... });

// Good
test('rejects email without domain', () => { ... });
test('accepts email with subdomain', () => { ... });
test('trims whitespace from email input', () => { ... });

Test Data Builders

Create readable test data:

// Builder pattern for test data
const user = UserBuilder.create()
  .withEmail('test@example.com')
  .withRole('admin')
  .withActiveSubscription()
  .build();

Integration Test Patterns

Test Through Public Interfaces

// Bad: Testing internal implementation
test('repository uses correct SQL', () => {
  const sql = userRepo.buildQuery();
  expect(sql).toContain('SELECT * FROM users');
});

// Good: Testing behavior through public API
test('finds users by email domain', async () => {
  await userRepo.save(createUser({ email: 'a@corp.com' }));
  await userRepo.save(createUser({ email: 'b@corp.com' }));

  const users = await userRepo.findByDomain('corp.com');

  expect(users).toHaveLength(2);
});

Use Real Dependencies Where Practical

// Prefer real database for repository tests
beforeAll(async () => {
  testDb = await createTestDatabase();
});

afterEach(async () => {
  await testDb.truncateAll();
});

// Mock only external services
jest.mock('./paymentGateway', () => ({
  charge: jest.fn().mockResolvedValue({ success: true })
}));

Contract Testing

Verify API contracts between services:

// Consumer contract
describe('User API Contract', () => {
  test('GET /users/:id returns user shape', async () => {
    const response = await api.get('/users/123');

    expect(response).toMatchSchema({
      id: expect.any(String),
      email: expect.any(String),
      createdAt: expect.any(String),
    });
  });
});

E2E Test Patterns

Critical Path Focus

Only test the most important user journeys:

// Priority 1: Revenue-critical paths
test('complete purchase flow', async () => {
  await page.addToCart(product);
  await page.checkout();
  await page.enterPayment(validCard);
  await page.confirmOrder();

  await expect(page.orderConfirmation).toBeVisible();
});

// Priority 2: Core functionality
test('user registration and login', async () => {
  await page.register(newUser);
  await page.login(newUser);

  await expect(page.dashboard).toBeVisible();
});

Page Object Pattern

Encapsulate page interactions:

class CheckoutPage {
  constructor(page) {
    this.page = page;
  }

  async enterShippingAddress(address) {
    await this.page.fill('#street', address.street);
    await this.page.fill('#city', address.city);
    await this.page.fill('#zip', address.zip);
  }

  async submitOrder() {
    await this.page.click('[data-testid="submit-order"]');
    await this.page.waitForURL('**/confirmation');
  }
}

Resilient Selectors

Use stable selectors that survive UI changes:

// Fragile: Based on CSS/position
await page.click('.btn-primary');
await page.click('div > div:nth-child(2) > button');

// Stable: Based on test IDs or roles
await page.click('[data-testid="submit-button"]');
await page.getByRole('button', { name: 'Submit' });

Coverage Strategy

Coverage Types

Type Measures Target
Line Lines executed 80%
Branch Decision paths taken 75%
Function Functions called 90%
Statement Statements executed 80%

Coverage Prioritization

Focus coverage on high-risk areas:

High Priority (100% coverage):
├── Payment processing
├── Authentication/Authorization
├── Data validation
├── Business rule enforcement
└── Security-sensitive code

Medium Priority (80% coverage):
├── Core business logic
├── API endpoints
├── Data transformations
└── Error handling

Lower Priority (60% coverage):
├── UI components
├── Configuration
├── Logging/Monitoring
└── Admin features

Meaningful Coverage

Coverage quantity vs quality:

// 100% coverage, low value
test('getter returns value', () => {
  user.name = 'John';
  expect(user.name).toBe('John');
});

// 80% coverage, high value
test('rejects order when inventory insufficient', () => {
  const inventory = createInventory({ quantity: 5 });
  const order = createOrder({ quantity: 10 });

  expect(() => processOrder(order, inventory))
    .toThrow('Insufficient inventory');
});

Quality Gates

Gate Configuration

Gate Threshold Enforcement
Unit Tests 100% pass Block merge
Integration Tests 100% pass Block merge
E2E Tests 100% pass Block deploy
Line Coverage ≥ 80% Block merge
Branch Coverage ≥ 75% Block merge
New Code Coverage ≥ 90% Warn
Test Duration < 10 min Warn

Flaky Test Management

Flaky Test Protocol:
1. DETECT: Track test stability over time
2. QUARANTINE: Move flaky tests to separate suite
3. FIX: Prioritize fixing within 1 week
4. REINTEGRATE: Return to main suite after 10 consecutive passes

Test Performance Budgets

Test Type Target Duration Action if Exceeded
Single Unit Test < 10ms Investigate
Unit Suite < 30s Parallelize
Single Integration < 1s Review setup/teardown
Integration Suite < 2 min Parallelize
Single E2E < 30s Optimize waits
E2E Suite < 10 min Reduce scope

Test Organization

File Structure

src/
├── user/
│   ├── User.ts
│   ├── User.test.ts           # Unit tests co-located
│   ├── UserRepository.ts
│   └── UserRepository.test.ts
├── order/
│   ├── Order.ts
│   └── Order.test.ts
tests/
├── integration/
│   ├── api/
│   │   └── users.test.ts      # API integration tests
│   └── database/
│       └── repositories.test.ts
└── e2e/
    ├── checkout.spec.ts       # E2E tests by journey
    └── registration.spec.ts

Test Naming Conventions

# Unit tests: [unit].test.ts
User.test.ts
OrderCalculator.test.ts

# Integration tests: [feature].integration.test.ts
users.integration.test.ts
payment-gateway.integration.test.ts

# E2E tests: [journey].e2e.ts or [journey].spec.ts
checkout.e2e.ts
user-onboarding.spec.ts

Test Data Management

Test Data Principles

  1. Isolation: Each test manages its own data
  2. Cleanup: Tests clean up after themselves
  3. Determinism: Same test, same data, same result
  4. Minimal: Only create data needed for the test

Factories and Fixtures

// Factory: Dynamic test data
const createUser = (overrides = {}) => ({
  id: faker.string.uuid(),
  email: faker.internet.email(),
  name: faker.person.fullName(),
  ...overrides
});

// Fixture: Static reference data
const ADMIN_USER = {
  id: 'admin-001',
  email: 'admin@test.com',
  role: 'admin'
};

Database Test Patterns

// Transaction rollback pattern
beforeEach(async () => {
  transaction = await db.beginTransaction();
});

afterEach(async () => {
  await transaction.rollback();
});

// Truncate pattern (slower but more isolated)
afterEach(async () => {
  await db.truncateAll();
});

CI/CD Integration

Pipeline Configuration

test:
  stages:
    - lint-and-typecheck    # Fast feedback first
    - unit-tests            # Parallel execution
    - integration-tests     # With test database
    - e2e-tests             # Against staging environment

  parallelization:
    unit: 4 workers
    integration: 2 workers
    e2e: 1 worker (sequential for stability)

  artifacts:
    - coverage reports
    - test results (JUnit XML)
    - E2E screenshots/videos on failure

Failure Handling

On Test Failure:
1. Capture: Screenshots, logs, database state
2. Report: Notify team channel
3. Block: Prevent merge/deploy
4. Retry: Once for E2E (flaky detection)

Best Practices

Do

  • Test behavior, not implementation
  • Keep tests independent and isolated
  • Use meaningful, descriptive test names
  • Maintain test code like production code
  • Run tests frequently during development
  • Fix flaky tests immediately

Avoid

  • Testing private methods directly
  • Mocking everything (use real dependencies where practical)
  • Ignoring slow tests (fix the root cause)
  • Writing tests after bugs (write them before)
  • Sharing state between tests
  • Over-relying on E2E tests

References

04 同仓库更多 Skills

shengdabai
shengdabai/Tony-Claude-Code-Skills

xiaolai-methodology

以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 "李笑来"、"笑来"、"笑来老师"、"扮演李笑来"、"找笑来聊聊"、"笑来怎么看"、"xiaolai"、"把时间当作朋友"、"通往财富自由之路"、"定投改变命运"、"韭菜的自我修养"、"自学是门手艺"、"让时间陪你慢慢变富"、"七年就是一辈子"、"元认知"、"活在未来"、"复利/长期主义"、"践行"、"痴迷改进"、"个人商业模式/出售时间"、"睡后收入"、"定投"、"财富自由"、"操作系统升级"、"最少必要知识"、"北极星提示词"、"用 AI 该怎么学/思考" 等任一触发词,或当用户带着关于创业/赚钱/投资/学习/职业/重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。

写作与文案
★ 3
shengdabai
shengdabai/Tony-Claude-Code-Skills

zread

Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `./.zread/wiki/`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module/package explanations, or "what does this repo do"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread / zread.ai directly. Also use it proactively before diving into a large unknown repo — if `./.zread/wiki/current` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word "zread".

开发工程师Skill与智能体开发
★ 3
shengdabai
shengdabai/Tony-Claude-Code-Skills

youtube

Launch the YouTube Creator Agent to auto-generate videos. Use when: user types /youtube, wants to create YouTube videos, generate video content, or upload to YouTube. Keywords: youtube, video, 视频, 创作视频, 发布视频

内容创作者Skill与智能体开发
★ 3
shengdabai
shengdabai/Tony-Claude-Code-Skills

youtube-script-sync

Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新/同步/优化 Youtube视频逐字稿知识库”, or says “更新/同步/优化该知识库” while this knowledge base is the active context.

Skill与智能体开发
★ 3
shengdabai
shengdabai/Tony-Claude-Code-Skills

writing-skills

How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.

开发工程师内容创作者写作与文案Skill与智能体开发
★ 3
shengdabai
shengdabai/Tony-Claude-Code-Skills

writing-rules

How to write .claude/rules/ files that Claude actually follows. Use when creating, improving, or reviewing project rules.

内容创作者写作与文案
★ 3