CodeVetter · Repo Unpack · Testing signals
immich-app/immich
Testing is layered: Vitest unit tests co-located as *.spec.ts in server/src and web/src, a 'medium' tier in server/test/medium that runs against a real Postgres via testcontainers, API-level e2e specs in e2e/ (Vitest + supertest-style SDK calls against a docker-compose stack), and Playwright browser/UI/maintenance projects. CI (.github/workflows/test.yml) shards jobs per changed directory. Coverage is configured but explicitly excludes some files, and several infra-heavy areas (storage.core is covered, but websocket/adapter and plugin internals have thin coverage).
- Server unit tests run with vitest config test/vitest.config.mjs: name 'server:unit', globals on, include 'src/**/*.spec.ts', swc transform, v8 coverage scoped to src/cores, src/services, src/utils, src/sql-tools.
- A separate medium tier (test/vitest.config.medium.mjs, 'pnpm test:medium') runs integration-style specs in server/test/medium/specs (exif, repositories, services, sync, workflow) with a globalSetup.ts, using testcontainers (devDependency) for real Postgres.
- Tests use a factory/stub pattern: server/test/factories/*.factory.ts (asset, auth, user, session, shared-link, person, etc.) plus server/test/fixtures/*.stub.ts and small.factory.ts/medium.factory.ts builders.
- Most controllers and services have co-located .spec.ts files (e.g., asset-media.controller.spec.ts, auth.service.spec.ts, queue.service.spec.ts) — the dominant convention is one spec per source file.
- e2e/ runs Vitest API specs (src/specs/{server,web,maintenance} covering api, cli, immich-admin) and three Playwright projects (web, ui, maintenance) driven by playwright.config.ts against a docker-compose stack (e2e/docker-compose.yml).
- Web unit tests run via vitest inside vite.config.ts: name 'web:unit', happy-dom environment, svelteTesting plugin, setup file src/test-data/setup.ts, TZ=UTC.
- CI test.yml gates on a pre-job change filter and runs: server unit+lint (mise //server:ci-unit), server medium tests, web lint+unit, cli unit on linux+windows, e2e server-cli and e2e web matrices on ubuntu amd64+arm64 with docker compose up and artifacted docker logs/playwright reports.
- check-openapi.yml enforces that the generated spec is in sync with the code and migration-order.yml verifies migration ordering — both are dedicated CI workflows.
- machine-learning has pytest tests (test_main.py, conftest.py) and a locustfile.py for load testing the predict endpoint.
- Mobile has a Flutter test/ tree and integration_test/ directory; mobile CI is exercised through build-mobile.yml rather than the main test workflow. (inferred)
- Coverage config explicitly excludes api.service.ts and microservices.service.ts from instrumentation, and files like websocket.adapter.ts, plugin.service.ts, and several controllers have no co-located spec — thin spots in otherwise high coverage.