This document explains how to run IVISS tests and quality checks locally, and how those checks map to CI.
IVISS has separate backend and frontend test stacks.
Backend:
- Rust test runner:
cargo test(or use nextest for fast tests runner) - Async tests: Tokio
- HTTP/app integration tests: Axum + Tower
- Database integration tests: Testcontainers + PostgreSQL
- External provider tests: local mocks and
mockito - Coverage in CI:
cargo-llvm-cov+nextest - Static checks:
cargo fmt,cargo clippy,cargo audit,cargo doc
Frontend:
- Unit/component test runner: Vitest
- DOM environment:
jsdom - React tests: Testing Library
- Coverage provider: V8
- Static checks: ESLint, Prettier, TypeScript, Vite build
- Generated API client checks: OpenAPI codegen before build/lint/type/test jobs
CI workflows live in .github/workflows/.
Use these commands before opening a PR.
Backend:
cd iviss-backend
cargo fmt --all -- --check
cargo clippy -- -D warnings
cargo testFrontend:
cd frontend
npm run lint:check
npm run prettier:check
npm run ts:check
npm run test
npm run buildIf a frontend change depends on API types, regenerate the client first:
cd frontend
npm run codegenBackend tests are located in:
iviss-backend/src/tests/
Some query-level tests also live next to implementation modules under iviss-backend/src/queries/.
Run all backend tests:
cd iviss-backend
cargo testRun a specific test module or test name:
cd iviss-backend
cargo test auth_queries_tests
cargo test test_admin_login_successRun tests with output:
cd iviss-backend
cargo test -- --nocaptureDatabase-backed tests start isolated PostgreSQL containers with Testcontainers and then run sqlx::migrate!("./migrations"). Docker must be running for these tests.
Use mock providers for SMS/email in tests. Do not call real SMS, email, OCR, or external government providers from automated tests.
Run backend formatting:
cd iviss-backend
cargo fmt --all -- --checkRun Clippy:
cd iviss-backend
cargo clippy -- -D warningsRun Rust security audit:
cd iviss-backend
cargo auditThe CI audit currently ignores specific known advisories in .github/workflows/backend-ci.yml. If an advisory must be ignored, document why in the workflow or Cargo audit config instead of hiding the failure locally.
Build Rust docs:
cd iviss-backend
cargo doc --no-deps --verboseRun the backend local CI helper:
cd iviss-backend
./scripts/test_flow.shThis script builds, tests with coverage instrumentation, checks formatting, runs Clippy, runs audit, builds docs, and generates an HTML coverage report.
Generate backend coverage manually:
cd iviss-backend
./scripts/coverage.shCI uses cargo-llvm-cov with nextest and uploads an HTML coverage artifact.
Frontend tests are colocated with code under __tests__/ folders or src/test/.
Run all frontend tests:
cd frontend
npm run testRun tests in watch mode:
cd frontend
npm run test:watchRun coverage:
cd frontend
npm run coverageVitest configuration lives in frontend/vitest.config.ts.
Important frontend test helpers:
frontend/src/test/setup.ts: globaljest-domsetup and browser API shims.frontend/src/test/queryWrapper.tsx: fresh React Query wrapper for hook/component tests.
Frontend test conventions:
- Use Testing Library queries that match user-visible behavior.
- Use
MemoryRouterfor route-dependent components. - Use
createQueryWrapper()for hooks/components that depend on TanStack Query. - Mock generated OpenAPI hooks/services at the boundary for component tests.
- Stub browser APIs such as
fetch,navigator.geolocation,matchMedia, storage, camera, and IndexedDB behavior when needed. - Clear
localStorage, mocks, timers, and global stubs between tests.
Run ESLint:
cd frontend
npm run lint:checkRun Prettier check:
cd frontend
npm run prettier:checkRun TypeScript:
cd frontend
npm run ts:checkRun production build:
cd frontend
npm run buildRun OpenAPI codegen:
cd frontend
npm run codegenThe frontend CI runs OpenAPI codegen before build, lint, Prettier, TypeScript, and unit test jobs. Generated files under frontend/src/openapi-rq/ should be regenerated, not edited manually.
Backend CI runs on pull requests and pushes to main and dev when backend files or the backend workflow change.
Backend jobs:
- Gitleaks secret scan.
- Rust build.
- Test and coverage with
cargo-llvm-covandnextest. - Rust doc tests.
- HTML coverage report generation.
- Rust formatting.
- Clippy with warnings denied.
- Cargo audit.
- Rust documentation build.
Frontend CI runs on pull requests and pushes to main and dev when frontend files or the frontend workflow change.
Frontend jobs:
npm ci --legacy-peer-deps- OpenAPI codegen.
- Vite build.
- ESLint.
- Prettier check.
- TypeScript check.
- Unit tests with coverage.
- SonarQube scan using frontend LCOV coverage.
Docker and deploy workflows are separate from unit test workflows, but test failures should be fixed before relying on deployment jobs.
Gitleaks is configured through .gitleaks.toml and runs in backend CI.
Run a local secret scan from the repository root when touching env, deployment, or docs with example secrets:
docker run --rm -v "$PWD:/path" zricethezav/gitleaks:latest detect --source="/path" -v --redact --config=/path/.gitleaks.tomlRules:
- Never commit real JWT private keys, API keys, database passwords, provider credentials, or production URLs.
- Prefer safe placeholders in docs and
.env.examplefiles. - If a test needs cryptographic material, use clearly fake test fixtures and ensure they are allowlisted intentionally.
Backend endpoint change:
- Handler success and error cases.
- DTO serialization/deserialization.
- Auth/RBAC behavior if protected.
- Query behavior if database-backed.
- OpenAPI/codegen impact if frontend consumes it.
Database change:
- Migration applies cleanly to an empty database.
- Query tests cover new columns, constraints, filters, and indexes.
- Seed data still works when
SEED_DATA=true. - Existing workflow tests still pass.
Frontend UI change:
- Component rendering and user-visible states.
- Hook behavior and loading/error/success states.
- Route guard behavior if navigation or roles changed.
- API hook integration with generated types.
Auth/session change:
- Access token and refresh behavior.
- Session revocation and logout behavior.
- Device activation and daily login flows.
- Role-specific access paths.
Infrastructure or deployment change:
- Relevant script syntax and dry-run checks where available.
- Docker build if container behavior changes.
- Documentation updates for any operator-facing command or secret.
Before opening a PR:
- Run the quick local checks for the changed subsystem.
- Add or update tests for new behavior and regressions.
- Regenerate OpenAPI client when the API contract changes.
- Review test data for secrets or production identifiers.
- Update developer docs if setup, test commands, CI behavior, or generated artifacts change.