Skip to content

Testing

INVA builds test-first: behaviour ships with its test in the same PR, and CI runs the suite on every push. A bug fix starts with a failing test.

Strategy by repo type

Repo Framework What "tested" means
Services (emma-platform, emma-gateway) unittest / pytest + coverage unit tests per module, integration tests behind env gates, coverage floor enforced
Static site (inva-is) site checks + Lighthouse link/format/accessibility/performance QA, not unit tests
Infrastructure (inva-infrastructure) queue CI + --check schema/lint/CLI tests for tooling; ansible-playbook --check, tofu plan for changes

Conventions (services)

  • One test file per moduletests/test_<module>.py mirrors the module.
  • Arrange / Act / Assert, asserting on outcomes not incidental detail.
  • Dependency-gated skips: tests needing an optional dependency self-skip when it is absent (@unittest.skipUnless(...)), so the pure core stays runnable anywhere and the full suite runs in CI where the deps are installed.
  • No shared/production resources: database-backed tests self-skip without an explicit disposable DSN; never point a test at a live system.
  • Determinism: inject time, clients and randomness — no real network or wall clock in a unit test.

Coverage

Coverage is measured on every run and gated in each repo's config ([tool.coverage.report] fail_under for Python). Do not lower the floor to make a change pass — add the missing test. Raise the floor as integration tests land for currently-uncovered surfaces (database adapters, server entrypoints); landing those also lets relaxed type modules move into the strict set (see coding standards).

The one command

make check runs every gate locally — the same set CI runs. If it is green, the PR's checks will be too.