Skip to main content

Testing Overview

The Competition Factory provides comprehensive testing utilities and patterns for building reliable tournament management applications. The testing toolkit includes mock data generation, test servers, and best practices for testing tournament scenarios.

Testing Tools​

mocksEngine - Primary Testing Tool​

The mocksEngine is the primary tool for generating test data. It creates realistic tournaments, participants, draws, match outcomes, and complete tournament scenarios with full CODES schema compliance.

Quick Start:

import { mocksEngine } from 'tods-competition-factory';

const { tournamentRecord } = mocksEngine.generateTournamentRecord({
drawProfiles: [{ drawSize: 32 }],
});

Key Capabilities:

Learn More: Getting Started with mocksEngine

factory-server - Test Server​

The factory-server provides a lightweight test server for integration testing and development. It simulates backend tournament management without requiring full infrastructure setup.

Testing Approaches​

Unit Testing​

Test individual factory methods in isolation:

import { tournamentEngine } from 'tods-competition-factory';

test('can add participant to tournament', () => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord();
tournamentEngine.setState(tournamentRecord);

const participant = { participantName: 'Test Player' };
const result = tournamentEngine.addParticipant({ participant });

expect(result.success).toBe(true);
});

Scenario Testing​

Test specific tournament scenarios and edge cases:

test('handles BYEs in elimination draw', () => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
drawProfiles: [
{
drawSize: 16,
participantsCount: 13, // Creates 3 BYEs
},
],
});

tournamentEngine.setState(tournamentRecord);
const { upcomingMatchUps } = tournamentEngine.tournamentMatchUps();

// Verify BYE handling
const byeMatchUps = upcomingMatchUps.filter((m) => m.matchUpStatus === 'BYE');
expect(byeMatchUps.length).toBe(3);
});

Test Data Strategies​

Minimal Setup​

Generate only what you need for each test:

// Minimal tournament for testing participant methods
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
participantsProfile: { participantsCount: 10 },
});

Complete Scenarios​

Generate fully populated tournaments for integration tests:

// Complete tournament with multiple events, venues, and scheduling
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
eventProfiles: [
{ eventType: 'SINGLES', drawProfiles: [{ drawSize: 32 }] },
{ eventType: 'DOUBLES', drawProfiles: [{ drawSize: 16 }] },
],
venueProfiles: [{ courtsCount: 8, venueName: 'Main Stadium' }],
schedulingProfile: [{ scheduleDate: '2024-06-01', venues: [{ rounds: [{ roundNumber: 1 }] }] }],
});

Progressive Building​

Build test data incrementally as needed:

test('can add multiple draws to event', () => {
// Start with minimal tournament
const { tournamentRecord, eventIds } = mocksEngine.generateTournamentRecord({
participantsProfile: { participantsCount: 0 },
eventProfiles: [{ eventName: 'Singles' }],
});

// Add singles draw
mocksEngine.modifyTournamentRecord({
tournamentRecord,
eventProfiles: [{ eventId: eventIds[0], drawProfiles: [{ drawSize: 32, drawName: 'Singles' }] }],
});

// Add doubles draw
mocksEngine.modifyTournamentRecord({
tournamentRecord,
eventProfiles: [
{
drawProfiles: [{ drawSize: 16, drawType: 'DOUBLES', drawName: 'Doubles' }],
},
],
});
});

Testing Best Practices​

1. Isolation​

Keep tests independent and repeatable:

// Good - each test creates its own data
test('test 1', () => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord();
// ... test logic
});

test('test 2', () => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord();
// ... test logic
});

2. Meaningful Data​

Use descriptive names and values for clarity:

const { tournamentRecord } = mocksEngine.generateTournamentRecord({
tournamentName: 'Test Tournament - BYE Handling',
drawProfiles: [
{
drawSize: 16,
participantsCount: 13, // Explicit: creates 3 BYEs
drawName: 'Main Draw',
},
],
});

3. Test Specific Scenarios​

Focus each test on a specific behavior:

test('seeded participants placed in correct positions', () => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
drawProfiles: [
{
drawSize: 16,
seedsCount: 4,
},
],
});

tournamentEngine.setState(tournamentRecord);
// Verify only seeding placement, not other aspects
});

4. Use Appropriate Completion​

Only complete matchUps necessary for your test:

// Test only needs first round complete
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
drawProfiles: [
{
drawSize: 16,
outcomes: [{ roundNumber: 1, scoreString: '6-1 6-2', winningSide: 1 }],
},
],
});

Testing Patterns​

Setup Helpers​

Create reusable setup functions:

function createStandardTournament() {
const { tournamentRecord, drawId } = mocksEngine.generateTournamentRecord({
drawProfiles: [{ drawSize: 32 }],
});
tournamentEngine.setState(tournamentRecord);
return { tournamentRecord, drawId };
}

test('can get draw positions', () => {
const { drawId } = createStandardTournament();
const { drawPositions } = tournamentEngine.getDrawPositions({ drawId });
expect(drawPositions.length).toBe(32);
});

Parameterized Testing​

Test multiple scenarios with the same logic:

test.each([
{ drawSize: 8, expectedRounds: 3 },
{ drawSize: 16, expectedRounds: 4 },
{ drawSize: 32, expectedRounds: 5 },
])('draw size $drawSize has $expectedRounds rounds', ({ drawSize, expectedRounds }) => {
const { tournamentRecord } = mocksEngine.generateTournamentRecord({
drawProfiles: [{ drawSize }],
});

tournamentEngine.setState(tournamentRecord);
const { matchUps } = tournamentEngine.allTournamentMatchUps();
const rounds = Math.max(...matchUps.map((m) => m.roundNumber));

expect(rounds).toBe(expectedRounds);
});

Resources​

Documentation​