Testing Standards
This document outlines the testing requirements for all contributions to Plus261.
Overview
Section intitulée « Overview »All code contributions must include appropriate tests. This ensures code quality and prevents regressions.
Testing Requirements
Section intitulée « Testing Requirements »New Features
Section intitulée « New Features »When adding new features, you must include:
- Unit Tests - Test individual functions and methods
- Integration Tests - Test component interactions
- Edge Case Tests - Test error conditions and boundaries
Bug Fixes
Section intitulée « Bug Fixes »When fixing bugs, you must:
- Write a Test - That reproduces the bug
- Fix the Bug - Make the test pass
- Verify - Ensure no regressions
Code Changes
Section intitulée « Code Changes »Any code change should:
- Maintain Coverage - Don’t decrease test coverage
- Update Tests - Update existing tests if behavior changes
- Add Tests - For new functionality
Test Types
Section intitulée « Test Types »Unit Tests
Section intitulée « Unit Tests »Test individual functions and classes in isolation.
Required for:
- Business logic functions
- Utility functions
- Service methods
- Complex calculations
Example:
describe('calculateTotal', () => { it('should sum item prices', () => { const items = [{ price: 10 }, { price: 20 }]; expect(calculateTotal(items)).toBe(30); });});Integration Tests
Section intitulée « Integration Tests »Test that multiple components work together.
Required for:
- API endpoints
- Database operations
- Service interactions
- Module integrations
Example:
describe('Product API', () => { it('should create and retrieve product', async () => { const product = await createProduct({ name: 'Test' }); const retrieved = await getProduct(product.id); expect(retrieved.name).toBe('Test'); });});Authorization Tests
Section intitulée « Authorization Tests »Test that permissions work correctly.
Required for:
- All protected endpoints
- Permission checks
- Role-based access
Example:
describe('Product Authorization', () => { it('should deny access without permission', async () => { const result = await queryProducts({ userId: 'user-without-permission' }); expect(result.errors[0].message).toContain('Unauthorized'); });});Coverage Requirements
Section intitulée « Coverage Requirements »Minimum Coverage
Section intitulée « Minimum Coverage »- Critical paths: 100%
- Business logic: >80%
- Utilities: >70%
- Overall project: >75%
Coverage Exceptions
Section intitulée « Coverage Exceptions »Some code may be excluded from coverage:
- Type definitions
- Configuration files
- Generated code
- Test utilities
Document exceptions with comments:
/* istanbul ignore next */function debugOnlyFunction() { // ...}Test Quality Standards
Section intitulée « Test Quality Standards »Test Structure
Section intitulée « Test Structure »Follow the Arrange-Act-Assert pattern:
it('should calculate discount', () => { // Arrange const price = 100; const discountPercent = 10;
// Act const result = calculateDiscount(price, discountPercent);
// Assert expect(result).toBe(90);});Test Naming
Section intitulée « Test Naming »Use descriptive test names:
// ✅ Goodit('should throw NotFoundError when user does not exist', () => {});
// ❌ Badit('test getUserById', () => {});Test Independence
Section intitulée « Test Independence »Each test should be independent:
// ✅ GoodbeforeEach(() => { // Set up fresh test data});
// ❌ Badlet sharedData; // Tests depend on each otherRunning Tests
Section intitulée « Running Tests »Before Submitting MR
Section intitulée « Before Submitting MR »# Run all testsbun test
# Check coveragebun test --coverage
# Code quality (monorepo root)bun --bun run check:codeTest Commands
Section intitulée « Test Commands »# Run all testsbun test
# Run in watch modebun test:watch
# Run with coveragebun test --coverage
# Run specific test filebun test path/to/test.test.tsTest Review Checklist
Section intitulée « Test Review Checklist »When reviewing PRs, check:
- Tests are included for new features
- Tests cover edge cases
- Tests are independent
- Test names are descriptive
- Coverage meets requirements
- Tests pass in CI
- No flaky tests
Common Issues
Section intitulée « Common Issues »Flaky Tests
Section intitulée « Flaky Tests »Flaky tests are tests that sometimes pass and sometimes fail.
Causes:
- Timing issues
- Shared state
- Random data
- External dependencies
Solutions:
- Use fake timers
- Isolate test data
- Mock external dependencies
- Use deterministic data
Slow Tests
Section intitulée « Slow Tests »Tests should run quickly.
Optimization:
- Use mocks instead of real services
- Use in-memory database for tests
- Parallelize tests when possible
- Skip expensive setup when not needed
Next Steps
Section intitulée « Next Steps »- Testing Guide - Comprehensive testing guide
- Development Workflow - Development process
- Code Style - Coding conventions