Skip to main content

Testing Guide

Excalidraw uses comprehensive testing to ensure code quality and prevent regressions. This guide covers testing practices, tools, and workflows.

Testing Framework

Vitest

Excalidraw uses Vitest as its test framework:
  • Fast: Extremely fast test execution
  • Vite-powered: Uses Vite’s transformation pipeline
  • Jest-compatible: Compatible with Jest API and matchers
  • TypeScript: First-class TypeScript support

Testing Libraries

Running Tests

Basic Commands

Running Specific Tests

Running All Test Suites

This runs:
  1. yarn test:typecheck - TypeScript type checking
  2. yarn test:code - ESLint code quality checks
  3. yarn test:other - Prettier formatting checks
  4. yarn test:app --watch=false - All unit/integration tests

Test Coverage

Coverage Requirements

Excalidraw enforces minimum coverage thresholds:

Viewing Coverage

Coverage Reports

Generated in coverage/ directory:
  • index.html - Interactive HTML report
  • lcov.info - LCOV format for CI tools
  • coverage-summary.json - JSON summary

Writing Tests

Test File Location

Place test files next to the code they test:
Or in a tests/ directory:

Test File Naming

  • *.test.ts - Unit tests for utilities
  • *.test.tsx - Component tests
  • *.spec.ts - Spec/integration tests
  • __snapshots__/ - Snapshot files (auto-generated)

Basic Test Structure

Testing Patterns

Unit Testing Utilities

Testing React Components

Testing with Jotai Atoms

Testing Async Code

Snapshot Testing

Update snapshots with:

Testing Canvas Operations

Canvas operations are mocked by vitest-canvas-mock:

Mocking

Mocking Functions

Mocking Modules

Mocking Timers

Test Organization

Describe Blocks

Group related tests:

Setup and Teardown

Testing Best Practices

Do’s

  1. Test Behavior, Not Implementation: Focus on what code does, not how
  2. Write Descriptive Test Names: Use “should” statements
  3. Follow AAA Pattern: Arrange, Act, Assert
  4. Test Edge Cases: Include boundary conditions and error cases
  5. Keep Tests Independent: Each test should run in isolation
  6. Use Meaningful Assertions: Be specific about expected outcomes
  7. Test User Interactions: Simulate real user behavior
  8. Mock External Dependencies: Isolate the code under test

Don’ts

  1. Don’t Test Implementation Details: Test the public API
  2. Don’t Write Brittle Tests: Avoid testing exact HTML structure
  3. Don’t Skip Error Cases: Always test error handling
  4. Don’t Test Third-Party Code: Trust external libraries
  5. Don’t Use Magic Numbers: Define constants for test data
  6. Don’t Share State Between Tests: Reset state in hooks
  7. Don’t Over-Mock: Mock only what’s necessary

Debugging Tests

Run Tests in Debug Mode

Use Test UI

Opens an interactive UI to:
  • Browse and run specific tests
  • View test results and coverage
  • Debug test failures

Console Logging

Debug in VS Code

Add to .vscode/launch.json:

Continuous Integration

Pre-commit Checks

Tests run automatically via Husky pre-commit hook:

Before Committing

Always run before committing:

CI Workflow

GitHub Actions runs these checks on PRs:
  1. Type checking: yarn test:typecheck
  2. Linting: yarn test:code
  3. Formatting: yarn test:other
  4. Tests: yarn test:app --watch=false
  5. Coverage: Uploads coverage reports

Common Testing Scenarios

Testing Element Operations

Testing Keyboard Shortcuts

Testing Collaboration Features

Resources

Next Steps

Now that you understand testing:
  1. Review the Contribution Guidelines for code standards
  2. Find an issue on the roadmap
  3. Write tests for your changes before submitting PRs
  4. Join Discord if you need help with testing