Testing at AptixLabs is layered, not exhaustive. The standard we hold to is "no crash, no data loss, no broken auth flow" — and the tests follow that priority.
The four layers
- Pure logic — anything that takes data in and returns data out — gets Vitest unit tests
- Firestore security rules — tested with the official Firebase emulator so a bad write can't reach production
- Mobile end-to-end — Detox on a real-device farm for the auth + workout + sync flows
- Web end-to-end — Playwright smoke + visual regression against staging on every deploy
What we deliberately don't test
The studio doesn't chase 100% coverage. It covers the paths that, if they break, lose user trust: auth, payments, programme writes, any AI tool-call boundary. UI snapshot tests on pure-display components are skipped — they break on every styling change and add no real safety.
Visual regression with Playwright
Every staging deploy captures full-page screenshots of every route at desktop and mobile widths. The CI diffs against a baseline; differences over a threshold open a PR comment for review. This catches CSS regressions that pass type-check and unit tests.
Before every store release
- Manual exploratory testing on a real device, real network
- Crash-free-session rate check on the previous build
- A 24-hour TestFlight + internal-test soak before promoting to production
Why we do not chase coverage numbers
A 100%-coverage badge is mostly vanity. It rewards testing trivial code and says nothing about whether the paths that matter actually work. We invert the question: what, if it broke silently, would lose a user's trust? Auth, payments, data writes, the AI tool-call boundary. Those get real tests. A pure-display component that changes every design tweak gets none, because a snapshot test there breaks constantly and protects nothing.
The test that catches the scariest bug
The single highest-value test we write is on Firestore security rules, run in the official emulator. A logic bug shows up as a broken feature; a rules bug shows up as one user reading another user's data — a breach, not a bug. So every rule has a test that asserts both what should be allowed and what must be denied. It is the cheapest insurance against the most expensive kind of failure.
