Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implement changes using Test-Driven Development (Red-Green-Refactor). Use for bug fixes, new features, or any code change that should have test coverage.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 16% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 147% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 160% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 49% | 0% |
Use this procedure directly in the primary conversation for every code change, regardless of size. The user may switch that conversation to the lower-cost implementation model before beginning the Red-Green-Refactor cycle.
Implement code changes using strict Red-Green-Refactor. Iron law: no production code without a failing test first.
Wrote code before a test? Delete it. Start over from a failing test.
/e2e — Follow this procedure when the current task needs Playwright E2E coverage./pr-fixup — After the task-defined checks pass and the PR opens, use itonly for CI or actionable reviewer findings.
Skip for: pure UI components (we don't test React components), config files, generated code.
For UI rendering bugs, prefer extracting or using a pure helper and testing that helper. Add Playwright only when the behavior is truly visual or integration-level. Avoid adding React component tests just to assert DOM output; that does not match this project's testing convention.
apps/backend/): test file next to source as *_test.go. Run:bash cd apps/backend && go test -v -run TestName ./internal/path/to/package/...
apps/web/lib/): test file next to source as *.test.ts. Run:bash cd apps && pnpm --filter @kandev/web test -- --run path/to/file.test.ts
apps/web/e2e/): follow /e2e when the current task needs Playwright tests.Choose the right level:
/e2e.Prefer state/output assertions over interaction assertions. Mock only slow, nondeterministic, or external boundaries; use real implementations or fakes when they keep the test deterministic.
For failure-path tests, inject the error at the boundary the production code claims to handle and exercise the real downstream call chain; do not short-circuit by mocking the handler under test.
When adding or renaming a field that crosses backend, WebSocket, and frontend boundaries, use rg to trace every producer, DTO, store upsert or partial merge, reconnect/readiness handler, and consumer before editing. Add focused coverage at the affected boundaries, including refresh/reconnect and an update that omits the field, so a partial payload cannot silently discard an existing value.
Test ordering-sensitive behavior with channels, barriers, or controllable fakes; do not use sleeps to create a race, except for a bounded, named delay that models a known poll-loop schedule when synchronization would alter that relationship. Pause at the ownership boundary, start the competing operation, then release. Exercise the real delivery path where practical, and prove the old interleaving fails before the fix. Assert both the winner state and the untouched replacement state, including relevant buffers, signals, or queue ownership. Cover stale events acting after a replacement operation begins, cancellation/retry ownership, and at-most-once delivery when they apply. Run affected Go packages with -race.
When delayed state has a lifecycle owner, pair the boundary tests: disposal before the threshold must cancel timers and emit nothing later; disposal or replacement after publication must immediately clear externally observable state; and stale callbacks must not mutate the replacement.
For a brand-new Go package, create the package directory and minimal test package first, then run the focused package test so RED fails on behavior rather than package-selection or import errors.
Exception: a reviewer-requested test that documents behavior already present on the current head is valid test-only contract coverage. Label it as such, make no production change, and run the focused suite.
For bug fixes, use the Prove-It Pattern: reproduce the bug with a failing test before changing production code. A fix without a regression test is not complete unless the change is explicitly untestable and you say why.
describe/it blocks (TS), remove duplicationIn tests, prefer DAMP over DRY: each test should read like a small specification. Shared helpers are fine when they remove noise, but not when they hide the scenario.
Return to step 1 for the next behavior or edge case. Continue until the feature or fix is complete.
Run the targeted tests named in the task file and report their results. Commit and open the PR after all affected task checks pass; do not add broad local verification by default.
After the final production-code edit, rerun every new or changed regression test and report the exact command and result. A prior green run does not cover a later patch.
Don't test implementation details:
Don't test mock behavior:
*-mock test ID, mock return value), you're testing the mock, not the code. Test real behavior or don't mock it.Don't add test-only methods to production code:
destroy(), reset(), _testHelper() that only tests call — put these in test utilities, not production classes.Mock minimally and understand dependencies:
Don't use incomplete mocks:
vi.mock() factories and add the export to each factory. Focused tests can pass while a full suite fails on an out-of-date module shape.
Never swallow errors in tests:
try/catch that silently ignores failures in test helpers or setup — these hide real failures.Don't repeat unchanged passing commands for reassurance:
reviewer-requested test-only contract coverage
Other measured skills in the registry, with their headline benchmark lift.