Test Strategy
How we test the monorepo before any user reaches it. Owners: Detta (QA targets) + Saiqul (CI enforcement). Built in Phase 0; applied from Phase 1 onward.
Test pyramid
Many fast unit tests, fewer component tests, a small set of high-value E2E. Do not E2E everything — E2E only the ranked critical paths.
/\ E2E (Cypress + Playwright) — ~15–25 specs, critical paths only
/ \ Component (Cypress CT / Vitest + Vue Test Utils) — ported shared-ui
/----\ Unit (Vitest) — shared-lib / shared-api / shared-store / helpers
/------\
Tooling (to be installed — Phase 0)
| Layer | Tool | Scope |
|---|---|---|
| Unit | Vitest | packages/shared-*, pure logic, Pinia stores, helpers |
| Component | Vitest + @vue/test-utils or Cypress CT | shared-ui components |
| E2E | Cypress | critical user flows on dev-server / staging |
| Cross-browser / mobile | Playwright | smoke across browsers + mobile viewports (Capacitor web) |
| Accessibility | axe-core (in Cypress) | critical screens |
| Performance | Lighthouse CI | staging, perf budgets (Phase 3) |
All wired into Turbo (turbo run test:unit, cached) and gated in CI.
Coverage targets (per FSD layer)
Global minimum is 80%; tier by risk:
| Layer | Target | Test type |
|---|---|---|
shared-lib, shared-helper, shared-api | 90% | unit |
shared-store (Pinia) | 85% | unit |
shared-ui | 80% | component |
pages / features / widgets | critical paths E2E-covered; unit where logic exists | E2E + unit |
apps/ionic (shell, routing) | smoke + E2E | E2E |
CI fails any package below its threshold.
CI gates (required PR checks on main)
linttypecheck(Turbo-cached)test:unit+ coverage thresholdtest:e2e(critical paths, on PR or pre-merge)
Branch ruleset on main makes all four required — no merge while red.
Conventions
- TDD per PR: a ported function/store/component lands with its test in the same PR (rule: write test first, RED → GREEN → refactor). No “tests later”.
- Test against test-mode APIs — never production payment/booking rails.
- Staging is the E2E target (
hh-ionic-staging.pages.dev) so specs run against a real deploy, not just local. - Flaky E2E are quarantined (tagged, tracked) — never silently retried into green.
Environments
| Env | URL | Use |
|---|---|---|
| Local dev | pnpm dev:ionic / dev-server | unit + component + local E2E |
| Staging | hh-ionic-staging.pages.dev (pnpm build:ionic:staging, .env.staging) | E2E, perf, load, device matrix |
| Production | ionic.hungryhub.com (hh-ionic CF Pages) | canary only, gated |