Unit Tests
Test individual functions and modules in isolation. Dependencies are mocked. These run fast and cover the majority of the codebase.
OpenScouter requires a minimum of 80% test coverage. Tests are not an afterthought. They are written before or alongside the implementation.
The team follows a red-green-refactor cycle:
This sequence keeps the implementation honest. A test written after the code tends to validate what the code already does rather than what it should do.
Unit Tests
Test individual functions and modules in isolation. Dependencies are mocked. These run fast and cover the majority of the codebase.
Integration Tests
Test how modules work together. API route handlers are tested against a real database connection using a test database. Stripe and AI provider calls are stubbed.
End-to-End Tests
Test complete user flows in a real browser using Playwright. These cover the critical paths listed below and run in CI on every pull request.
npm run test # unit and integration tests (Jest)npm run test:watch # watch mode during developmentnpm run test:coverage # with coverage reportnpm run test:e2e # end-to-end tests (Playwright)Coverage reports are written to coverage/. The CI pipeline enforces the 80% threshold and fails the build if coverage drops below it.
The following paths must have E2E test coverage at all times. Regressions in these areas block a release.
The invite token flow covers:
The AI analysis pipeline covers:
The notes quality gate covers:
The payout flow covers:
The Telegram notification flow covers:
Place unit tests in the same directory as the file they test, named <filename>.test.ts.
Place integration tests under tests/integration/.
Place E2E tests under tests/e2e/.
Each test file should have a clear describe block that names the unit under test and individual it or test blocks that describe the specific behaviour being verified. Avoid generic names like it('works').
Mock only what you must. A test that mocks too much tests the mocks, not the code.