# 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 ```bash # 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 ```bash # 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: ```typescript 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: ```typescript import { describe, it, expect } from 'vitest'; import { render, screen } from '@testing-library/react'; import { MyComponent } from '../MyComponent'; describe('MyComponent', () => { it('should render correctly', () => { render(); 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: ```typescript 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/`: ```typescript // app/test/fixtures/league.ts export const mockLeague = { id: 'league-1', name: 'Test League', // ... }; ``` Import and use in tests: ```typescript 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: ```bash 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 ```bash # 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 ```bash # 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 - [Vitest Documentation](https://vitest.dev/) - [React Testing Library](https://testing-library.com/react) - [Cypress Documentation](https://docs.cypress.io/) - [Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)