Skip to main content

Testing

All TypeScript packages test with Vitest. Run the unit tests of the package you change while you work, then the E2E suites when a change affects module wiring, persistence or a protocol flow. pnpm test at the root runs the test script of every package.

SuiteLocationCommandCI job
Backend unit and architectureapps/backend/src/**/*.spec.ts, apps/backend/test/architecture/pnpm --filter @eudiplo/backend testTest Coverage Report
Backend E2Eapps/backend/test/**/*.e2e-spec.tspnpm --filter @eudiplo/backend test:e2e:localE2E Tests (non-OIDF)
OIDF conformanceapps/backend/test/oidf/pnpm --filter @eudiplo/backend test:oidfE2E Tests (OIDF)
CLIapps/cli/test/**/*.test.ts, apps/cli/src/**/*.spec.tspnpm --filter @eudiplo/cli testBuild CLI
Config format, SDKpackages/*/src/**/*.spec.ts, packages/eudiplo-sdk-core/test/pnpm --filter @eudiplo/config-format test, pnpm --filter @eudiplo/sdk-core test—
Client unitapps/client/src/**/*.spec.tspnpm --filter @eudiplo/client testBuild Client
Client browser (Playwright)apps/client/e2e/pnpm --filter @eudiplo/client e2enot run
Documentation toolingapps/docs/scripts/pnpm --filter @eudiplo/docs testBuild Documentation

CI is defined in .github/workflows/ci-and-release.yml and runs on pull requests, the merge queue and pushes to main.

Backend unit tests​

Unit tests sit next to the code as *.spec.ts and run with SWC (apps/backend/vitest.config.ts):

pnpm --filter @eudiplo/backend test # all unit tests
pnpm --filter @eudiplo/backend test:watch
pnpm --filter @eudiplo/backend exec vitest run src/session/application/session-store.spec.ts
pnpm --filter @eudiplo/backend test:debug # with the Node inspector

Test use cases with fake ports, without a Nest TestingModule. Adapters with several implementations share a contract suite (*.contract.ts, for example test/session/session-repository.contract.ts) that runs against SQLite and PostgreSQL.

The architecture checks (src/platform/module-boundaries.spec.ts, test/architecture/dependency-rules.spec.ts) run with the unit tests. What they enforce and how to update the ratchet baseline: Backend architecture.

E2E testing​

Backend E2E tests start the assembled Nest application and drive it over HTTP. They live under apps/backend/test/, grouped by area (issuance/, presentation/, session/, trust-list/, config-portability/, persistence/, key/, …) with shared helpers in utils.ts, utils-mdoc.ts and shared/, and fixtures in fixtures/.

Running E2E tests locally​

pnpm --filter @eudiplo/backend test:e2e:local

The script builds @eudiplo/config-format and runs every suite except the OIDF conformance tests, without coverage. Prerequisites:

  • Port 3000 must be free. The suites start the backend there and abort with a clear error when the port is taken. Stop pnpm dev:backend or a Compose stack first, and do not run two E2E runs in parallel.
  • Docker is optional. The PostgreSQL, HashiCorp Vault and S3 (RustFS) suites start containers with Testcontainers. Without a container runtime they are skipped with a warning. Set E2E_SKIP_CONTAINERS=true to skip them on purpose. In CI (CI set) a missing runtime fails the run.

You need no .env file, no hosts entry and no running test-rp webhook:

  • The suites ignore apps/backend/.env, so development settings cannot leak into a run. Test defaults (secrets, DB_SYNCHRONIZE=true, both OUTBOUND_URL_ALLOW_* flags) come from the env block of apps/backend/test/vitest.config.ts.
  • Outgoing webhook and trust-list calls to localhost:8787 are mocked with nock.

Capability settings such as the public and internal URLs are read once when the Nest module is compiled. Set them in the Vitest env block or with vi.stubEnv before the module is created; ConfigService.set() afterwards has no effect.

Watch mode and coverage​

pnpm --filter @eudiplo/backend test:e2e:watch # re-run on change
pnpm --filter @eudiplo/backend test:e2e # with coverage, as in CI

The CI job also adds the host.testcontainers.internal hosts entry and starts test-rp; locally neither is required.

OIDF conformance testing​

The conformance tests run the OpenID Foundation conformance suite locally and execute its OID4VCI issuer and OID4VP verifier test plans against EUDIPLO. Testcontainers starts the suite (MongoDB, the suite server and its nginx front end on port 8443); the tests start the backend at https://host.testcontainers.internal:3000. No public deployment and no hosted suite are needed.

Prerequisites:

  • Docker, and free ports 3000 and 8443.

  • A hosts entry so the suite containers and your machine resolve the backend the same way:

    echo "127.0.0.1 host.testcontainers.internal" | sudo tee -a /etc/hosts

Run them:

pnpm --filter @eudiplo/config-format build
pnpm --filter @eudiplo/backend test:oidf
FilePurpose
oidf-issuance.e2e-spec.tsOID4VCI issuer test plans
oidf-presentation.e2e-spec.tsOID4VP verifier test plans
oidf-setup.tsContainer lifecycle
oidf-suite.tsClient for the suite's API, log export
oidf-issuer-modules.snapshot.json, oidf-verifier-modules.snapshot.jsonModules the plans contain; rewritten when the suite's plan changes, so commit the updated file
VariableDefaultEffect
VITE_OIDF_MODULESallComma-separated module filter
VITE_OIDF_MODULE_PATTERN—Regular expression module filter
VITE_OIDF_ENFORCE_MODULE_COVERAGEfalseFail instead of warn when scenarios are not covered
VITE_OIDF_URLhttps://localhost:8443Suite URL
VITE_OIDF_DEMO_TOKEN—API token for the suite
VITE_DOMAINhost.testcontainers.internal:3000Host of the backend's PUBLIC_URL
OIDF_EXPORT_LOGS (or VITE_OIDF_EXPORT_LOGS)onExport suite logs; false speeds up local runs
OIDF_TEARDOWN_PER_FILE (or VITE_OIDF_TEARDOWN_PER_FILE)onTear the containers down after each spec file; false reuses them within one run

Logs land in tmp/oidf-logs/<planId>/ and, for failed modules, tmp/oidf-logs/failed/<testInstanceId>/. CI uploads them as the oidf-test-results artifact. Wait thresholds (OIDF_WAIT_*) and how to calibrate them are described in apps/backend/test/oidf/README.md.

Client tests​

Unit tests run with Vitest through the Angular builder; the Playwright browser tests are not part of CI. Setup and conventions: Client development.

Coverage​

ReportCommandOutput
Backend unitpnpm --filter @eudiplo/backend exec vitest run --coverage --config ./vitest.config.tsapps/backend/coverage/unit/
Backend E2Epnpm --filter @eudiplo/backend test:e2eapps/backend/coverage/e2e/

Both write text, LCOV (HTML under lcov-report/) and Cobertura reports. The Test Coverage Report CI job runs both and uploads the Cobertura files to GitHub Code Quality (labels backend-unit and backend-e2e) for pushes and for pull requests from branches of the repository. Static analysis runs on SonarCloud, configured in .sonarcloud.properties (backend and client sources; the client is excluded from coverage).