Skip to content

Testing

OpenScouter requires a minimum of 80% test coverage. Tests are not an afterthought. They are written before or alongside the implementation.

Test-Driven Development

The team follows a red-green-refactor cycle:

  1. Red — Write a failing test that describes the desired behaviour. Run it and confirm it fails.
  2. Green — Write the minimum implementation needed to make the test pass. Run it and confirm it passes.
  3. Refactor — Clean up the code without changing behaviour. Run the tests again to confirm nothing broke.

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.

Test Types

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.

Running Tests

Terminal window
npm run test # unit and integration tests (Jest)
npm run test:watch # watch mode during development
npm run test:coverage # with coverage report
npm 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.

Critical Paths

The following paths must have E2E test coverage at all times. Regressions in these areas block a release.

Token Validation

The invite token flow covers:

  • Generating a valid invite token
  • Accepting an invite with a valid token
  • Rejecting an expired token
  • Rejecting a token that has already been used

Agent Pipeline

The AI analysis pipeline covers:

  • Submitting a completed test for analysis
  • Confirming the pipeline processes notes correctly
  • Confirming the generated report contains expected sections
  • Handling pipeline failures without data loss

Notes Gate

The notes quality gate covers:

  • Blocking submission when the note count is below the minimum threshold
  • Allowing submission when the threshold is met
  • Displaying the correct count and guidance message to the tester

Payouts

The payout flow covers:

  • Triggering a payout after a test is approved
  • Confirming the correct amount is sent to the correct Stripe recipient
  • Handling Stripe errors and surfacing them without corrupt state

Telegram Integration

The Telegram notification flow covers:

  • Sending a notification when a new test becomes available
  • Confirming the message contains the correct study details
  • Handling bot errors without affecting the core platform

Writing New Tests

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.