Skip to main content

Overview

Lichess has comprehensive test coverage for both backend and frontend:
  • Backend tests: Scala tests using munit and scalacheck
  • Frontend tests: TypeScript tests using Node.js test runner

Backend Testing

Test Framework

Lichess uses munit as the primary testing framework:

Property-Based Testing

scalacheck is used for property-based testing:

Running Tests

All Tests

Run all tests in the project:

Module Tests

Test specific modules:

Specific Test Class

Run a single test class:

Pattern Matching

Run tests matching a pattern:

Single Test

Run a specific test within a class:

Test Organization

Tests are located in each module’s test directory:

Test Dependencies

Test utilities are available via the tests.bundle:
Includes:
  • munit
  • scalacheck
  • munitCheck (integration)
  • chess.testKit

Test-Only Dependencies

Access test utilities from other modules:
This allows using test helpers from the common module.

Writing Tests

Test Coverage

Modules with extensive test coverage:
  • game: Game logic, PGN, move validation
  • rating: Glicko-2 calculations
  • user: User accounts, authentication
  • tournament: Pairing algorithms
  • study: Analysis board logic
  • puzzle: Puzzle rating

Frontend Testing

Test Framework

Frontend tests use Node.js built-in test runner:

Running Tests

Use the ui/test script:

Test Location

Tests are in tests/ subdirectories:

Example Test

Test Build Process

The test runner:
  1. Compiles TypeScript tests to JavaScript
  2. Runs tests with Node.js test runner
  3. Reports results

Watch Mode

Continuously run tests on file changes:
Output:

Integration Testing

Manual Testing

For full integration testing:

Browser Testing

Lichess uses Browserstack for cross-browser testing. Supported browsers:
  • Firefox 115+
  • Chrome/Chromium 112+
  • Edge 109+
  • Safari 13.1+
  • Opera 91+

Continuous Integration

GitHub Actions

Tests run automatically on every commit:

Pre-commit Hooks

Run tests before committing:

Test-Driven Development

Recommended TDD workflow:

Debugging Tests

Backend Test Debugging

Add debug output:
Run with verbose output:

Frontend Test Debugging

Use Node.js debugger:
Or add console output:

Performance Testing

Backend Performance

Benchmark critical code paths:

Frontend Performance

Time-based assertions:

Test Best Practices

Do

  • ✅ Write tests for new features
  • ✅ Test edge cases and error conditions
  • ✅ Keep tests fast and focused
  • ✅ Use descriptive test names
  • ✅ Test behavior, not implementation
  • ✅ Run tests before committing

Don’t

  • ❌ Test private implementation details
  • ❌ Write tests that depend on external services (without mocks)
  • ❌ Create flaky tests that pass/fail randomly
  • ❌ Ignore failing tests
  • ❌ Write tests that are slower than the code they test

Troubleshooting

Tests Fail Locally but Pass in CI

  • Check for environment-specific issues
  • Verify dependencies are up-to-date
  • Check system time/timezone settings

Flaky Tests

  • Add .ignore to investigate later:
  • Increase timeouts for async tests
  • Avoid tests that depend on timing

Slow Tests

Next Steps

Additional Resources