AI skills in use in my daily
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

3.8 KiB

name description
test-driven-development Write the failing test before the implementation, for every feature or bugfix - red, green, refactor. Use before writing any implementation code, and when fixing a bug (reproduce it as a failing test first). Covers what makes a good test, why the order matters, the rationalizations that mean you are skipping it, and a verification checklist before marking work complete. Triggers: add a feature, fix this bug, implement X, write tests, TDD.

Write the test first. Watch it fail. Write minimal code to pass.

Core principle: if you didn't watch the test fail, you don't know if it tests the right thing.

The Iron Law: NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST. Wrote code before the test? Delete it — completely, don't keep it "as reference" — and start over from tests.

Always use for: new features, bug fixes, refactoring, behavior changes. Exceptions (ask the user first): throwaway prototypes, generated code, configuration files.

Red-Green-Refactor Cycle

RED — Write a failing test. One minimal test showing what should happen. One behavior, clear name, real code (avoid mocks unless unavoidable).

Verify RED — watch it fail (mandatory, never skip). Run just that test. Confirm: it fails (not errors), the failure message is what you'd expect, and it fails because the feature is missing — not because of a typo. If it passes, you're testing existing behavior — fix the test. If it errors, fix the error and re-run until it fails correctly.

GREEN — write the minimal code to pass. Don't add extra features, options, or "improvements" beyond what the test requires (YAGNI).

Verify GREEN — watch it pass (mandatory). Run the test — and the full suite. Confirm it passes, no other tests broke, and output is clean (no errors/warnings). If it fails, fix the code, not the test.

REFACTOR — clean up while green. Remove duplication, improve names, extract helpers. Don't add new behavior. Keep tests green throughout.

Repeat for the next behavior.

Good Tests

Minimal (one thing — "and" in the name means split it), clear (name describes behavior, not "test1"), and shows intent (demonstrates the desired API).

Why Order Matters

Tests written after code pass immediately — which proves nothing (might test the wrong thing, might test implementation not behavior, might miss edge cases you forgot). Test-first forces you to watch it fail, proving it actually tests something. Manual testing is ad-hoc — no record, can't re-run, easy to forget cases under pressure.

Common Rationalizations (all mean: stop, do TDD properly)

"Too simple to test" / "I'll test after" / "Already manually tested" / "Deleting X hours of work is wasteful" (sunk cost — keeping unverified code is technical debt) / "Keep as reference, write tests first" (you'll adapt it — that's testing after) / "Need to explore first" (fine — throw away exploration, start clean with TDD) / "Test is hard to write = design is unclear, but I'll push through anyway" (listen to the test) / "TDD will slow me down" (it's faster than debugging after).

Verification Checklist (before marking work complete)

  • Every new function/method has a test
  • You watched each test fail before implementing, for the expected reason
  • Wrote minimal code to pass each test
  • All tests pass, output pristine
  • Tests use real code (mocks only if unavoidable)
  • Edge cases and errors covered

Can't check all boxes? You skipped TDD — start over.

Debugging Integration

Bug found? Write a failing test reproducing it first, then follow the Red-Green-Refactor cycle. The test proves the fix and prevents regression. Never fix bugs without a test.

Final Rule

Production code → a test exists and failed first. Otherwise, it's not TDD. No exceptions without explicit user permission.