Files
agentic-dev/docs/decisions/adr-011-tdd-foundation.md
Danijel Martinek 2edc76002a refactor(docs): strip residual Phase/Plan setup-history references
Final sweep for setup-process bookkeeping not caught by template-reset-v1.
ADRs drop Plan-N qualifiers; spec collapses the historical 11-phase
migration table; scaffolding guide drops "Phase added" column; comment
prefixes referencing R-numbers in test describes / eslint inline comments
are normalized. Architecture-level rule IDs (R40, R52, E0, J0, etc.) are
preserved where they serve as stable cross-references in ADRs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:28:31 +02:00

2.8 KiB

ADR-011: TDD Foundation

Status: Accepted Date: 2026-05-05 Supersedes: none Spec: docs/superpowers/specs/2026-05-05-tdd-foundation-design.md

Context

The vertical-feature monorepo refactor (ADRs 001-010) established clean architecture with per-feature DI containers but did not enforce TDD as the path of least resistance. Agentic workers were producing code-first commits with tests added later, leading to test theatre and mock/real drift.

Decision

  1. New package @repo/core-testing (tag: tooling) — shared test utilities: defineFactory, defineContractSuite, renderWithProviders, mock-payload helpers, jsdom setup file. Tagged tooling so any package may depend on it as devDependency without boundary violation.

  2. Vitest base configs split into node + jsdom with safety defaults (clearMocks, restoreMocks, mockReset, unstubGlobals, sequence.shuffle) and coverage thresholds (80/75/80/80 baseline; 100% in entities + use-cases + controllers).

  3. Factories per feature in src/__factories__/ replace inline fixtures. Stable date defaults (2026-01-01) so snapshot diffs reflect SUT behavior only.

  4. Contract suites per repository interface in src/__contracts__/ run against every implementation (Mock + Payload). Eliminates the class of bug where the mock and the real impl drift apart.

  5. Tests in core-* packages and apps — composition smoke tests (appRouter, payloadConfig, bind-production, providers).

  6. Storybook test-runner — every story executed as a smoke test.

  7. CI workflow — typecheck + lint + boundaries + test + build + e2e + storybook on every PR. Coverage uploaded as artifact.

  8. Two new docs — tdd-workflow.md (process) + restructured adding-a-feature.md (interleaves tests with impl).

Alternatives considered

  • Fixture files instead of factories — rejected. Fixtures rot with schema changes and require manual updates per test.
  • One shared test file per impl — rejected. Contract suites give the same coverage in fewer LOC and prevent drift.
  • Real Postgres in tests via testcontainers — rejected for unit tests (slow, complex). Repository contract suites + vi.mock('payload') give equivalent confidence in milliseconds.
  • Stryker mutation testing — deferred. Coverage thresholds + contract suites get us most of the way; mutation testing is incremental.

Consequences

  • New package to maintain (small, mostly stable surface).
  • Coverage thresholds may fail builds initially; we add tests to cross threshold as features land.
  • Sequence shuffle may surface latent flakes; we fix as found.
  • Templates for new features now require writing tests first; this is by design.

Refines

  • ADR-006 (boundary tags) — adds @repo/core-testing as a tooling package.