Operations

Testing

Test suite overview, running tests, writing new tests, and coverage across all packages.

The Realtime Platform has 221+ automated tests across all 12 packages, run with Vitest.

Running Tests

# All tests across the monorepo
pnpm test

# Single package
pnpm --filter @realtime/backend test

# Watch mode
pnpm --filter @realtime/event-router test:watch

# With coverage
pnpm --filter @realtime/auth test -- --coverage

Test Breakdown

PackageTestsDescription
shared-utils20Date, error, and object utility tests
shared-config2Environment validation tests
observability3Logger tests
redis-layer7Key pattern tests
auth9JWT, permissions tests
event-router11Filters, normalizer, subscription registry
topic-registry19Service CRUD, validation, environment scoping
schema-registry16Service, compatibility checker, environment scoping
metrics11Dashboard metrics, hot topics analyzer
workers30Mapping evaluator, webhook signer/registry, CDC reader
backend76API routes, document service, debugger, trace store
sdk17RealtimeClient, EventBus
Total221+

Test Architecture

Tests use dependency injection throughout — all stores and services are injected via interfaces, so tests use in-memory implementations without requiring PostgreSQL or Redis.

// Example: testing the topics API route
const store = new InMemoryTopicStore();
const service = new TopicRegistryService(store);
const app = createApp({ topicService: service, /* ... */ });

// Test against the Express app directly
const response = await request(app)
  .post('/api/topics')
  .send({ name: 'test.topic', description: 'Test', owner: 'team' });

expect(response.status).toBe(201);

Writing New Tests

Create a test file

Place test files next to the source code with a .test.ts suffix:

packages/my-package/src/
  service.ts
  service.test.ts

Or in a __tests__/ directory:

apps/backend/src/api/
  topics.ts
  __tests__/
    topics.test.ts

Write the test

import { describe, it, expect, beforeEach } from 'vitest';

describe('MyService', () => {
  let service: MyService;

  beforeEach(() => {
    service = new MyService(new InMemoryStore());
  });

  it('should create an item', async () => {
    const result = await service.create({ name: 'test' });
    expect(result.name).toBe('test');
  });
});

Run the test

pnpm --filter @realtime/my-package test

Configuration

The root vitest.config.ts provides shared configuration for all packages:

  • Test framework: Vitest
  • Coverage provider: v8
  • File pattern: **/*.test.ts

Best Practices

  • Use in-memory store implementations for unit tests (no external dependencies)
  • Test both success and error paths
  • Test environment/application scoping for all entity operations
  • Use beforeEach to reset state between tests
  • Keep tests focused — one assertion concept per test