agentleFS
Ygohel18Ygohel18/skills/testing-strategy/SKILL.md

testing-strategy

Skill1 starsChanged 46 days agoMITView on GitHub

Language-agnostic framework for designing, structuring, and evaluating automated test suites. Triggers whenever an agent is asked to "write tests for this", "what should I test?", "is this well tested?", "how much test coverage do I need?", "this test is flaky", or when debating unit vs integration vs e2e tests. Enforces the test pyramid, behavior-driven testing over implementation details, strict mocking discipline, root-cause resolution for flaky tests, and using coverage as a risk signal rather than a vanity metric.

54 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use api-contract-design, deploy-checklist and 9 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • MohOneXSkill

    api-contract-design

    Designs and reviews API contracts (REST, RPC, GraphQL, library interfaces) for evolvability, backward compatibility, and failure semantics. Use when defining new endpoints/interfaces, versioning an API, reviewing a schema, or deciding how breaking changes propagate to clients.

    Also in 3 projects that use this

  • AnthropicSkill

    deploy-checklist

    Pre-deployment verification checklist. Use when about to ship a release, deploying a change with database migrations or feature flags, verifying CI status and approvals before going to production, or documenting rollback triggers ahead of time.

    Also in 4 projects that use this

  • xenitV1Skill

    react-patterns

    Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices.

    Also in 4 projects that use this

  • AnthropicSkill

    tech-debt

    Identify, categorize, and prioritize technical debt. Trigger with "tech debt", "technical debt audit", "what should we refactor", "code health", or when the user asks about code quality, refactoring priorities, or maintenance backlog.

    Also in 4 projects that use this

  • MicrosoftSkill

    error-handling

    统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用。

    Also in 5 projects that use this

  • Microsoft AzureSkill

    release-readiness

    Complete ODIN release documentation and validation checks before declaring user-visible work complete, preparing a release, or opening the Release-to-main pull request.

    Also in 3 projects that use this

  • +4 more from anthropics

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 5 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 44 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Dependencies: Use lightweight real dependencies (Testcontainers, in-memory SQLite, local test servers).

    line 49
  2. Distinctive:

    Thin Glue / API Gateways: When an application is primarily a router/orchestrator with almost no internal algorithmic logic, unit tests add …

    line 57
  3. Distinctive:

    Test public inputs and outputs, not private methods or internal state variables.

    line 69
  4. Distinctive:

    The Refactoring Test: If you rewrite the internal implementation without changing the public contract, your tests should still pass.

    line 70
  5. Distinctive:

    If a test requires 30 lines of mock configuration to test 3 lines of business code, stop.

    line 87
  6. Very specific:

    Order Dependence: Test B passes only if Test A ran first.

    line 101

“Common” is measured: kept by at least 6 in 10 of the 44 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Testing Strategy & Architecture

A language-agnostic operational standard for deciding what to test, how much to test, and at which layer of the test pyramid.

Sibling Standards:

  • For general test writing guidelines, see universal-coding-standards.
  • For evaluating test adequacy during code review, see code-review.

1. Test Pyramid & Level Selection

Select the right test level based on execution cost and isolation needs:

       ▲
      / \        E2E Tests (~5-10%)
     /   \       Full user-journey through real UI/stack. Slow, expensive, high-confidence.
    /-----\
   /       \     Integration Tests (~20-30%)
  /         \    Verify 2+ real components interacting (Real DB, API contracts).
 /-----------\
/             \  Unit Tests (~60-70%)
/_______________\ Isolated functions, math, pure logic, fast in-memory execution.

Level Definitions:

  1. Unit Tests:
    • Scope: Verifies a single isolated function, class, or domain entity.
    • Dependencies: Mock out external slow boundaries (network, filesystem, time).
    • Speed: Milliseconds. Can run thousands on every file save.
  2. Integration Tests:
    • Scope: Verifies the real interaction between two or more components (e.g., repository layer against a real test database, serialization over HTTP).
    • Dependencies: Use lightweight real dependencies (Testcontainers, in-memory SQLite, local test servers).
    • Speed: Seconds. Run on git pre-push or PR validation.
  3. End-to-End (E2E) Tests:
    • Scope: Simulates a complete user workflow through the full system (e.g., signup $\rightarrow$ checkout $\rightarrow$ invoice generation).
    • Dependencies: Real running services.
    • Speed: Minutes. Reserve strictly for mission-critical core paths.

When to Invert the Pyramid Deliberately:

  • Thin Glue / API Gateways: When an application is primarily a router/orchestrator with almost no internal algorithmic logic, unit tests add little value. Shift weight toward integration tests verifying real payload contracts.
  • UI-Heavy Frontends: Core component interactions are often best validated through component integration tests (e.g. React Testing Library) rather than purely isolated unit tests.

2. What to Test (The Quality Standard)

  • 2.1 New Logic Always Gets a Test: Never excuse missing tests with "it's simple" or "it's just a helper". Bugs live in the simple things.
  • 2.2 Dual Coverage (Happy Path + Boundary Case): Every unit of business logic must test:
    1. The primary successful outcome (happy path).
    2. At least one boundary, empty, or error condition (edge case: null input, negative value, timeout, unauthorized state).
  • 2.3 Test Behavior, Not Implementation Details:
    • Test public inputs and outputs, not private methods or internal state variables.
    • The Refactoring Test: If you rewrite the internal implementation without changing the public contract, your tests should still pass. If they break, you were testing implementation details.
  • 2.4 Don't Test the Framework: Never write tests verifying that language/framework primitives work (e.g., testing that a plain getter returns what a setter stored, or that a library's array sorting sorts).

3. Mocking Discipline & Anti-Patterns

Mocking is a necessary tool, but over-mocking destroys test confidence.

  • 3.1 What to Mock:
    • External I/O (Stripe, Twilio, third-party HTTP APIs).
    • Non-deterministic factors (current system time, random UUIDs, crypto salt).
    • Slow / dangerous resources (disk formatters, email sending).
  • 3.2 What NOT to Mock:
    • Internal business collaborators or adjacent helper classes. Let them run real code.
    • Language data structures (don't mock a Map or List).
  • 3.3 The "Over-Mocking" Smell:
    • If a test requires 30 lines of mock configuration to test 3 lines of business code, stop. You are testing your mock configuration, not production behavior.
  • 3.4 Prefer Fakes Over Canned Mocks:
    • Where practical, use lightweight stateful fakes (e.g., an in-memory repository implementing the interface) over rigid canned mocks (when(repo.get(1)).thenReturn(...)).

4. Diagnosing & Eliminating Flaky Tests

A flaky test is a high-priority bug in your test suite, never an acceptable nuisance. Never re-run a failing test in CI until it turns green without investigating.

Top 4 Causes of Test Flakiness:

  1. Shared Mutable State: Tests polluting a shared database, global variables, or singleton caches. Fix by isolating test contexts or truncating state in beforeEach/teardown.
  2. Unmocked Time & Race Conditions: Relying on real wall-clock delays (sleep(500)). Fix by using deterministic fake timers (vi.useFakeTimers(), time-machine).
  3. Async Polling / Missing Awaits: Code finishes after the test framework has already asserted. Fix by explicitly awaiting promises or polling conditions with a timeout.
  4. Order Dependence: Test B passes only if Test A ran first. Verify test suite independence by shuffling execution order (e.g., pytest --random-order, jest --randomize).

Quarantine Policy: If a flaky test cannot be fixed immediately, quarantine it with a skipped annotation (e.g. @pytest.mark.skip) and must link to an open tracking issue. Never delete tests silently.


5. Coverage as a Signal, Not a Target

  • 5.1 Coverage % is a Vanity Metric: 95% line coverage with weak or missing assertions provides false confidence.
  • 5.2 Prioritize Risk Over Percentages:
    • Critical paths (Authentication, Payment processing, State machines, Data integrity) require rigorous branch coverage.
    • Trivial boilerplate (DTOs, simple config maps, generated code) does not need coverage.
  • 5.3 Ban Tautological Tests: Reject tests written solely to hit coverage numbers without asserting meaningful behavioral outcomes (e.g. calling a function without an assert or expect).

6. Test Design & Structure

  • Scenario-Descriptive Naming: Name tests after the scenario and expected outcome:
    • ✅ returns_validation_error_when_email_lacks_at_symbol
    • ❌ test_email or test_error
  • AAA Pattern (Arrange, Act, Assert): Visually separate test execution into three clear blocks:
    // Arrange
    const cart = new ShoppingCart();
    cart.add(item, 2);
    
    // Act
    const total = cart.calculateTotal();
    
    // Assert
    expect(total).toBe(40.0);
  • Independent Execution: Every test must be completely isolated and capable of running in parallel or random order.

Detailed References

  • references/framework-notes.md: Canonical test idioms, parameterized tables, and mocking examples across pytest (Python), Vitest / Jest (JS/TS), Go testing, JUnit 5 (Java), cargo test (Rust), and PHP / Laravel (Pest & PHPUnit).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.