Testing
Complete testing strategy covering unit tests, integration tests, and end-to-end testing with real-world examples from the SaaS boilerplate.Table of Contents
Testing Architecture
The boilerplate implements a layered testing strategy that mirrors the application architecture:6 Testing Layers: From general testing patterns to specific E2E workflows, each layer has its own purpose and tooling.
1. General Testing Patterns
- Testing utilities and helpers
- Common mocking patterns
- Test data factories and builders
- Pure function testing
- Utility and helper functions
- Business logic validation
- React component behavior
- User interaction testing
- Visual regression testing
- Database operations
- Data layer validation
- Transaction testing
- Business logic and authorization
- API integration testing
- Error handling validation
- Complete user workflows
- Cross-browser compatibility
- Integration testing
Testing Stack & Configuration
Core testing technologies and configuration patterns:Multi-Project Setup:Key Features:
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [react(), tsconfigPaths()],
test: {
projects: [
// Client-side tests (jsdom environment)
{
name: 'client',
environment: 'jsdom',
include: ['src/**/*.test.{ts,tsx}'],
exclude: ['src/services/**/*.test.{ts,tsx}'],
setupFiles: ['./src/__tests__/setup-test.ts'],
globals: true,
},
// Server-side tests (node environment)
{
name: 'server',
environment: 'node',
include: ['src/services/**/*.test.{ts,tsx}'],
setupFiles: ['./src/services/__tests__/setup-mocks.ts'],
globals: true,
},
],
},
})- TypeScript Support: Full type checking during tests
- Watch Mode: Automatic re-running on file changes
- Coverage Reports: Built-in code coverage analysis
- Parallel Execution: Tests run concurrently for speed
Quick Start Guide
Get started with testing in minutes:Daily Testing Commands:
# Run all tests
pnpm test # Run unit tests
pnpm test:e2e # Run E2E tests
# Development workflow
pnpm test:watch # Watch mode for unit tests
pnpm test:ui # Open Vitest UI
pnpm test:e2e:ui # Open Playwright UI
# Coverage and debugging
pnpm test:coverage # Generate coverage report
pnpm test:e2e:headed # E2E with visible browser
# Specific tests
pnpm test user-service # Run matching pattern
pnpm test src/services/__tests__/user-service.test.tsDetailed Guides
Comprehensive guides for each testing layer:Testing by Layer
- General Testing - Testing utilities, mocking patterns, and common setup
- Unit Testing - Pure function testing with Vitest and TypeScript
- UI Component Testing - React component testing with Testing Library
- Repository Testing - Database layer testing with transactions and migrations
- Service Testing - Business logic, authorization, and integration testing
- E2E Testing - End-to-end workflows with Playwright
Essential Commands
# Unit testing
pnpm test # Run all unit tests
pnpm test:watch # Run tests in watch mode
pnpm test:coverage # Generate coverage report
pnpm test:ui # Open Vitest UI interface
# Specific test files
pnpm test user-service # Run tests matching pattern
pnpm test src/services/__tests__/user-service.test.ts
# End-to-end testing
pnpm test:e2e # Run all E2E tests
pnpm test:e2e:headed # Run with visible browser
pnpm test:e2e:ui # Open Playwright UIBest Practices Summary
Testing Philosophy: Write tests that document behavior, catch regressions, and give confidence when refactoring. Focus on testing behavior, not implementation details.
- Test Isolation: Each test should be independent and repeatable
- Descriptive Names: Test names should clearly describe what is being tested
- Arrange-Act-Assert: Structure tests with clear setup, execution, and validation
- Mock External Dependencies: Focus on testing your code, not third-party services
- Test Edge Cases: Include error conditions and boundary cases
- Use
vi.clearAllMocks()inbeforeEachto prevent test pollution - Run tests in parallel with proper environment separation
- Mock heavy operations like database calls and API requests
- Use test data factories for consistent, reusable test data
Testing Guides
🧪
General Testing
Foundational patterns, mocking strategies, and testing philosophy⚡
Unit Testing
Service functions, utilities, and isolated component logic🎨
UI Component Testing
React components, user interactions, and UI behavior🗄️
Repository Testing
Database operations, Drizzle queries, and data access patterns⚙️
Service Testing
Business logic, authorization, and service layer integration🌐
E2E Testing
Full application flows, user journeys, and Playwright automationTesting ready! The boilerplate includes comprehensive testing strategies that ensure code quality, catch regressions, and provide confidence when shipping new features.
