Testing
Where to colocate unit, integration, and e2e tests in a DMA project.
DMA defines placement of tests relative to modules, but doesn't pick the runner, coverage thresholds, or pyramid. One rule: the test lives next to the code it protects.
Unit tests — colocate
File *.test.ts (or *.spec.ts) — in the same folder as the implementation:
features/checkout/
├── checkout.store.ts
├── checkout.store.test.ts # store — internal
└── public/
└── checkout-page.tsx
services/cart/public/
├── cart.ts
└── cart.test.ts # service public API
shared/lib/
├── format-currency.ts
└── format-currency.test.tsdma check scans test files too — imports in *.test.ts / *.spec.ts enter the same graph as production code. Same rules: public-api, feature-to-feature, layer-direction, and the rest.
What to test directly
| Code | Test via |
|---|---|
| Internal store, composable | relative import in the same module |
services/*/public/* | import public file |
shared/lib/* | import helper |
What not to do
- Import another module's internals from a test — the gate fails the same as in production. Test through
public/or colocate the test inside the module with a relative import. - Root
__tests__/for the whole project — tests don't move with the module on refactor.
Component tests
SFC / React component tests — colocate next to the component:
features/catalog/public/
├── catalog-page.tsx
└── catalog-page.test.tsx # optionalRunner of choice: Vitest + Testing Library, @vue/test-utils, @testing-library/svelte. DMA examples' runnable tests are mostly pure TS (stores, services, lib) — no DOM harness.
Integration / route tests
Thin composition root (app/, routes/) — place for wiring checks if needed. More often — a separate folder at the app root:
apps/web/
├── src/
├── e2e/ # Playwright, Cypress
└── playwright.config.tsE2E doesn't colocate inside features/ — they cross multiple modules and routes.
Monorepo
Unit tests stay in the app package (apps/web/src/...). Workspace package tests — inside the package. dma check analyzes one graph per root (app or discovered package); graphs are not merged across the monorepo. See Monorepo.
Examples in the repo
| Example | Runner | Colocate |
|---|---|---|
| vite-react | Vitest | *.test.ts next to stores, cart, lib |
| next-app | Bun test | stores + format-currency |
| sveltekit-routes | Vitest | stores, cart, lib |
| astro-pages | Bun test | stores, cart, lib |
| vue-vite | Vitest | stores, composables, cart |