All skills
mattpocock avatar

/tdd

@3216582 official
by Matt Pocockmattpocock/skills274k stars
22,991

Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.

Use this Skill: https://skilld.dev/gh/mattpocock/skills/tdd

This session only. Nothing lands on disk.

tests.md

≈554 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Good and Bad Tests

Good Tests

Integration-style: Test through real interfaces, not mocks of internal parts.

// GOOD: Tests observable behavior
test("user can checkout with valid cart", async () => {
  const cart = createCart();
  cart.add(product);
  const result = await checkout(cart, paymentMethod);
  expect(result.status).toBe("confirmed");
});

Characteristics:

  • Tests behavior users/callers care about
  • Uses public API only
  • Survives internal refactors
  • Describes WHAT, not HOW
  • One logical assertion per test

Bad Tests

Implementation-detail tests: Coupled to internal structure.

// BAD: Tests implementation details
test("checkout calls paymentService.process", async () => {
  const mockPayment = jest.mock(paymentService);
  await checkout(cart, payment);
  expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
});

Red flags:

  • Mocking internal collaborators
  • Testing private methods
  • Asserting on call counts/order
  • Test breaks when refactoring without behavior change
  • Test name describes HOW not WHAT
  • Verifying through external means instead of interface
// BAD: Bypasses interface to verify
test("createUser saves to database", async () => {
  await createUser({ name: "Alice" });
  const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
  expect(row).toBeDefined();
});

// GOOD: Verifies through interface
test("createUser makes user retrievable", async () => {
  const user = await createUser({ name: "Alice" });
  const retrieved = await getUser(user.id);
  expect(retrieved.name).toBe("Alice");
});

Tautological tests: Expected value restates the implementation, so the test passes by construction.

// BAD: Expected value is recomputed the way the code computes it
test("calculateTotal sums line items", () => {
  const items = [{ price: 10 }, { price: 5 }];
  const expected = items.reduce((sum, i) => sum + i.price, 0);
  expect(calculateTotal(items)).toBe(expected);
});

// GOOD: Expected value is an independent, known literal
test("calculateTotal sums line items", () => {
  expect(calculateTotal([{ price: 10 }, { price: 5 }])).toBe(15);
});

Source: SKILL.md on GitHub

No alerts2d5 checks · Risk SAFE
  • Gen Agent Trust Hub2d

    This skill provides best practices and guidelines for Test-Driven Development (TDD). It is purely informational and contains no malicious code, unauthorized network requests, or sensitive data exposure.

  • Socket2d

    No alerts

  • Snyk2d

    Risk: LOW · No issues

  • Runlayer7mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 3216582. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 2 months ago

README badge

README badge for mattpocock/skills/tdd

Guides AI agents through test-driven development using vertical slices (one test, one implementation, repeat) rather than writing all tests upfront. Emphasizes integration-style tests that verify behavior through public interfaces and survive refactors, with a concrete workflow from planning through tracer bullets to incremental loops and refactoring.

Generated from the current SKILL.md.

Should I write all tests first, then all implementation?
No. Write one test, then implement to pass it, then repeat (vertical slices). Writing all tests upfront produces tests coupled to imagined behavior rather than actual behavior, and they won't catch real changes.
What kind of tests should I write?
Integration-style tests that exercise code through public APIs and verify observable behavior, not implementation details. Good tests read like specifications and survive refactors because they don't depend on internal structure.
Should I test private methods and internal functions?
No. Tests should only use public interfaces. If a test breaks when you refactor internal code without changing behavior, that test was testing implementation, not behavior.
Do I need to test every possible edge case?
No. Confirm with the user which behaviors are most important to test and focus effort on critical paths and complex logic rather than every edge case.

Generated from the current SKILL.md. These answers refresh after source changes.