This document outlines the testing infrastructure for the HIIT Timer application.
The HIIT Timer app uses the following testing tools:
- Jest: For unit and component testing
- React Testing Library: For testing React components
- Cypress: For end-to-end testing
To run the Jest tests:
npm testTo run Cypress tests:
npm run cypress:openTo run Cypress in headless mode:
npm run cypress:runTest coverage reports are generated automatically when running tests with Jest. The coverage threshold is set to 70% for statements, branches, functions, and lines.
To view the coverage report:
- Run the tests with
npm test - Open the coverage report in a browser:
open coverage/lcov-report/index.html
-
Dependencies:
jest- Testing framework@testing-library/react- React component testing utilities@testing-library/jest-dom- Custom DOM element matchers
-
Configuration Files:
jest.config.mjs- Main Jest configurationjest.setup.ts- Test setup and global mocksjest.d.ts- Type definitions for Jest- Type extensions in
types/directory
-
TypeScript Integration:
- Custom type definitions to support Jest matchers with TypeScript
- Configured
tsconfig.jsonto include test files and types - Reference types in test files with
/// <reference types="@testing-library/jest-dom" />
-
Dependencies:
cypress- End-to-end testing framework
-
Configuration Files:
cypress.config.ts- Cypress configuration with component and E2E testing setup- Component tests in
cypress/component/ - E2E tests in
cypress/e2e/
-
Running Cypress:
- Component Testing:
npm run component - E2E Testing:
npm run e2e
- Component Testing:
Tests are automatically run on each pull request and push to the main branch using GitHub Actions. The workflow:
- Runs all Jest tests
- Runs Cypress tests in headless mode
- Uploads coverage reports to Codecov (if configured)
Unit tests are located in the __tests__ directory, mirroring the structure of the source code. For example, tests for components in app/components are located in __tests__/components.
End-to-end tests are located in the cypress/e2e directory.
The testing setup includes comprehensive TypeScript support:
-
Type Definitions: Custom type definition files in the
types/directory:jest.d.ts: Base Jest type extensionsjest-dom.d.ts: Test-library specific matchersglobal.d.ts: Global interface extensionstesting-library.d.ts: Testing Library type augmentationsjest-extended.d.ts: Extended Jest matchersexpect-extend.d.ts: Chai assertion extensions
-
Configuration Files:
jest.setup.ts: TypeScript setup file for Jestjest.config.mjs: Jest configuration that references the TypeScript setup
-
tsconfig.json includes test files and type definitions to ensure proper type checking.
When writing component tests, follow these guidelines:
-
Import necessary testing utilities and matchers:
import { render, screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; // Explicitly import jest-dom
-
Use
renderfrom@testing-library/reactto render components -
Use queries like
getByText,getByRole, etc. to find elements -
Use
fireEventoruserEventto simulate user interactions -
Use
waitFororfindByqueries for asynchronous behavior
Example:
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import MyComponent from '@/app/components/MyComponent';
describe('MyComponent', () => {
it('renders correctly', () => {
render(<MyComponent />);
expect(screen.getByText('Hello')).toBeInTheDocument();
});
it('handles clicks', () => {
render(<MyComponent />);
fireEvent.click(screen.getByRole('button'));
expect(screen.getByText('Clicked')).toBeInTheDocument();
});
});When testing contexts, create a test component that uses the context hooks and test the behavior through that component.
-
Create component tests in
cypress/component/:import MyComponent from '../../app/components/MyComponent'; describe('<MyComponent />', () => { it('renders and functions correctly', () => { cy.mount(<MyComponent />); cy.get('button').click(); cy.contains('Clicked').should('be.visible'); }); });
-
Run with
npm run component
-
Create E2E tests in
cypress/e2e/:describe('App navigation', () => { it('navigates correctly', () => { cy.visit('/'); cy.get('a[href="/about"]').click(); cy.url().should('include', '/about'); }); });
-
Run with
npm run e2e
- Use Jest mocks for external dependencies
- Use
jest.spyOnto spy on methods - Mock context providers when necessary
- Test timeouts: Increase the timeout in Jest configuration or use
jest.setTimeout() - Async issues: Make sure to use
waitFor,findByqueries, oractfor asynchronous operations - TypeScript errors with Jest matchers:
- Make sure to explicitly import
@testing-library/jest-domin your test files - Check that your test file is included in the TypeScript compiler paths
- For new matchers, add them to the appropriate type definition file
- Ensure your
tsconfig.jsonincludes@testing-library/jest-domin types
- Make sure to explicitly import
Visual regression testing captures screenshots of components and UI elements to detect unintended visual changes during development. This helps ensure that UI updates don't accidentally break existing designs.
-
Tools:
- Cypress: For capturing screenshots
- Percy: For visual comparison between baseline and current snapshots
- Playwright: Alternative for advanced cross-browser visual testing
-
Setup:
npm install -D @percy/cypress
-
Configuration:
// cypress/support/e2e.js import '@percy/cypress';
-
Example Usage:
describe('Visual Regression', () => { it('should maintain visual consistency of the homepage', () => { cy.visit('/'); cy.percySnapshot('Homepage'); // Test different viewport sizes cy.viewport('iphone-x'); cy.percySnapshot('Homepage on Mobile'); }); });
-
Integration with CI:
- Connect Percy with GitHub Actions to run visual tests on each PR
- Add Percy token to GitHub secrets
- Automatic detection of unintended visual changes
- Cross-browser visual consistency
- Visual testing for responsive designs across device sizes
- UI component library quality assurance
- Set up Percy account and get API token
- Install Percy integration with Cypress
- Create baseline screenshots for critical UI components
- Add visual regression tests for key user flows
- Integrate with CI/CD pipeline
- Expand end-to-end test coverage
- Implement visual regression testing as outlined above