# Testing Strategy ## Test Layers | Layer | Tool | What to Test | |---|---|---| | Entities | Vitest (unit) | Zod schema validation, error classes | | Use Cases | Vitest (unit) | Business logic with mock implementations via DI | | Controllers | Vitest (unit) | Input validation, use case delegation, error mapping | | Infrastructure | Vitest (integration) | Real DB via test containers, Payload API calls | | UI Components | Vitest + Storybook | Rendering, props, accessibility | | Full App | Playwright (E2E) | User flows across both Next.js and TanStack Start | ## Running Tests ```bash pnpm test # All tests via Turborepo cd packages/core && pnpm vitest run # Core unit tests only cd packages/core && pnpm vitest watch # Core tests in watch mode ``` ## Test Pattern (DI Container) All tests that use the DI container must initialize and destroy it: ```typescript import "reflect-metadata"; import { beforeEach, afterEach } from "vitest"; import { initializeContainer, destroyContainer } from "@/di/container.js"; beforeEach(() => { initializeContainer(); }); afterEach(() => { destroyContainer(); }); ``` This ensures each test gets fresh mock instances (singleton scope resets). ## Test File Location - Core tests: `packages/core/tests/unit/{use-cases,controllers}/{domain}/` - UI tests: co-located next to component (`*.test.tsx`) - E2E tests: `tests/e2e/`