Testing

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
2. Unit Testing
  • Pure function testing
  • Utility and helper functions
  • Business logic validation
3. UI Component Testing
  • React component behavior
  • User interaction testing
  • Visual regression testing
4. Repository Testing
  • Database operations
  • Data layer validation
  • Transaction testing
5. Service Testing
  • Business logic and authorization
  • API integration testing
  • Error handling validation
6. End-to-End Testing
  • Complete user workflows
  • Cross-browser compatibility
  • Integration testing

Testing Stack & Configuration

Core testing technologies and configuration patterns:
Multi-Project Setup:
// 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,
      },
    ],
  },
})
Key Features:
  • 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.ts

Detailed Guides

Comprehensive guides for each testing layer:

Testing by Layer

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 UI

Best Practices Summary

Testing Philosophy: Write tests that document behavior, catch regressions, and give confidence when refactoring. Focus on testing behavior, not implementation details.
Key Principles:
  • 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
Performance Tips:
  • Use vi.clearAllMocks() in beforeEach to 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

Testing ready! The boilerplate includes comprehensive testing strategies that ensure code quality, catch regressions, and provide confidence when shipping new features.
    Testing | ShipSaaS Documentation | ShipSaaS - Launch your SaaS with AI in days