brackt/TESTING.md

4.5 KiB

Testing Guide

This document explains how to run and write tests for Brackt.com.

Overview

We use two testing frameworks:

  • Vitest + React Testing Library - Unit and component tests
  • Cypress - End-to-end integration tests

Running Tests

Unit Tests

# Run tests in watch mode (interactive)
npm test

# Run tests once (CI mode)
npm run test:run

# Run tests with UI
npm run test:ui

# Run tests with coverage
npm run test:coverage

E2E Tests

# Open Cypress interactive mode
npm run test:e2e

# Run Cypress headless (CI mode)
npm run test:e2e:headless

# Run all tests (unit + E2E)
npm run test:all

Writing Tests

Unit Tests

Unit tests go in __tests__ directories next to the code they test:

app/
  lib/
    utils.ts
    __tests__/
      utils.test.ts
  models/
    league.ts
    __tests__/
      league.test.ts

Example unit test:

import { describe, it, expect } from 'vitest';
import { myFunction } from '../myFunction';

describe('myFunction', () => {
  it('should do something', () => {
    const result = myFunction('input');
    expect(result).toBe('expected output');
  });
});

Component Tests

Component tests also go in __tests__ directories:

app/
  components/
    DraftGrid.tsx
    __tests__/
      DraftGrid.test.tsx

Example component test:

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { MyComponent } from '../MyComponent';

describe('MyComponent', () => {
  it('should render correctly', () => {
    render(<MyComponent title="Test" />);
    expect(screen.getByText('Test')).toBeInTheDocument();
  });
});

E2E Tests

E2E tests go in the cypress/e2e directory:

cypress/
  e2e/
    league-creation.cy.ts
    league-settings.cy.ts
    draft-room.cy.ts

Example E2E test:

describe('Feature Name', () => {
  it('should do something', () => {
    cy.visit('/some-page');
    cy.get('button').click();
    cy.findByText('Expected Text').should('exist');
  });
});

Test Fixtures

Reusable test data is stored in app/test/fixtures/:

// app/test/fixtures/league.ts
export const mockLeague = {
  id: 'league-1',
  name: 'Test League',
  // ...
};

Import and use in tests:

import { mockLeague } from '~/test/fixtures/league';

CI/CD Integration

Tests run automatically on:

  • Every push to main or develop
  • Every pull request

GitHub Actions Workflow

  1. Test Job - Runs unit tests with PostgreSQL service
  2. Typecheck Job - Runs TypeScript type checking
  3. Build Job - Builds Docker image (only on main branch)
  4. Deploy Job - Deploys to server (only after all tests pass)

Tests must pass before deployment!

Coverage

Coverage reports are generated automatically:

  • HTML report: coverage/index.html
  • JSON report: coverage/coverage-final.json

View coverage locally:

npm run test:coverage
open coverage/index.html

Best Practices

Unit Tests

  • Test one thing per test
  • Use descriptive test names
  • Mock external dependencies
  • Aim for 80%+ coverage

Component Tests

  • Test user interactions, not implementation
  • Use screen.getByRole() when possible
  • Test accessibility
  • Keep tests focused

E2E Tests

  • Test critical user flows
  • Use data-testid sparingly
  • Prefer semantic queries
  • Keep tests independent

Debugging Tests

Vitest

# Run specific test file
npm test -- path/to/test.test.ts

# Run tests matching pattern
npm test -- --grep "pattern"

# Debug in VS Code
# Add breakpoint and use "Debug Test" in test file

Cypress

# Open Cypress UI for debugging
npm run test:e2e

# Run specific test file
npx cypress run --spec "cypress/e2e/specific-test.cy.ts"

Common Issues

Tests fail locally but pass in CI

  • Check Node version matches CI (v20)
  • Ensure database is running locally
  • Check environment variables

Cypress tests timeout

  • Increase timeout in cypress.config.ts
  • Check if app is running on correct port
  • Verify selectors are correct

Coverage not generating

  • Ensure @vitest/coverage-v8 is installed
  • Check vitest.config.ts coverage settings
  • Run with npm run test:coverage

Additional Resources