UXDL Docs

Testing Overview

Testing pyramid, tools by framework, where each test runs, and the team's CI gate flow.

Quality is enforced at every stage — from a developer's laptop through Alpha, Beta, and Production. This page defines our testing strategy: the pyramid, the tools per app framework, where each test runs, and where Playwright E2E and Performance & Load testing fit.

Testing pyramid

LayerPurposeCI triggerSpeed
UnitPure functions, components in isolationEvery PR to alpha, beta, prodFast (seconds)
IntegrationModules + real DB / API boundariesEvery PR to alpha, beta, prodMedium (minutes)
E2ECritical user journeys in a real browserPR → Alpha preview, then Beta after mergeSlower (minutes)
Performance / LoadLatency, throughput, soak, realtime fan-outScheduled + pre-release on BetaLong (minutes–hours)
Manual QAExploratory + sign-offBeta, before promotionHuman

Where tests run

Each test type runs in specific places (local, GitHub Actions, or manual) and against specific environments. Use this matrix to know what executes where.

Test typeLocal (laptop)GitHub Actions (CI)ManualTarget environment
UnitOn demand✅ Every PR → alpha/beta/prodN/A (no deploy)
IntegrationWith test DB (Docker)✅ Every PR → alpha/beta/prodEphemeral test DB
E2E (smoke)localhost✅ On PRAlpha preview URL
E2E (full)On demand✅ On merge to betaBeta
Performance / LoadQuick baseline✅ Nightly schedule✅ Pre-releaseBeta (never Prod)
Manual QA✅ QA test planBeta
Synthetic monitoring✅ Continuous (cron)Production

See Environments for how Alpha → Beta → Prod promotion works, and Playwright CI for the actual workflow files.

Tools by app framework

Pick tools based on the app's framework. Unit/component tools differ per stack; Playwright is the single E2E standard across all web apps so end-to-end tests look the same everywhere.

FrameworkUnitComponentIntegrationE2E
AngularJasmine + Karma (default) · Vitest (modern, experimental)Angular TestBed (+ Testing Library)TestBed + HttpTestingControllerPlaywright
React + Next.jsVitest / JestReact Testing LibraryVitest + MSWPlaywright
React + ViteVitestReact Testing LibraryVitest + MSWPlaywright
React NativeJestRN Testing LibraryJest + MSWDetox / Maestro
Node.js (Express + TS)Vitest (recommended) · Jest (legacy) · node:test (built-in)Supertest + test DBPlaywright request
Python (FastAPI)pytesthttpx + TestClientPlaywright request

Frontend vs backend test commands

bash
# Angular
ng test              # Jasmine + TestBed (Karma, or experimental Vitest)
pnpm test:e2e        # Playwright
 
# React (Vite / Next.js)
pnpm test            # Vitest + Testing Library
pnpm test:e2e        # Playwright
 
# Node.js backend
pnpm test            # Vitest + Supertest (API integration)
 
# Python (FastAPI) backend
uv run pytest        # unit + TestClient integration

What Playwright covers

Playwright runs real browser tests against deployed applications:

  • User flows (login, checkout, dashboard navigation)
  • Cross-browser checks (Chromium, Firefox, WebKit)
  • Visual regression (optional, via screenshots)
  • API testing via the request fixture (no browser needed)

Playwright does not replace unit tests. Use it for critical user journeys that span multiple pages and services.

Required checks before merge

PR merge gate (alpha / beta / prod)

  1. pnpm lint — no lint errors.
  2. pnpm typecheck — no type errors.
  3. pnpm test — unit + integration pass (the enforced gate).
  4. Playwright smoke suite passes against the Alpha preview URL.
  5. For release PRs to prod: latest nightly load run is green (see Performance & Load).

How leading realtime/software teams test

Our flow follows the patterns used by high-scale realtime product teams (collaboration, chat, streaming). The principles below are what we aim for:

PrincipleWhat it means for us
Shift leftCheapest tests (unit/integration) run first, on every PR, before any deploy
Ephemeral preview per PREvery PR gets an Alpha preview URL that E2E runs against — no shared "dev breaks everyone" env
Trunk-based + fast CISmall PRs, fast gates; keep the merge queue green
Test the realtime pathWebSocket/Socket.io flows get dedicated E2E + load tests (presence, reconnection, fan-out)
Load test before launchBig launches run k6 load + soak against Beta with explicit SLO thresholds
Progressive deliveryPromote to Prod behind feature flags / canary; watch metrics before full rollout
Synthetic monitoringProd is continuously probed by scripted checks; alerts page on-call
Flaky = brokenA flaky test is treated as a failing test and fixed, never retried away

Documentation flow

GuideWhen to read
Playwright SetupFirst time setting up E2E locally
Writing E2E TestsAdding or updating test cases
CI IntegrationWiring Playwright into GitHub Actions
Performance & Load TestingLoad, stress, soak, and realtime perf

Official documentation