Testing Guide

Testing Guide

New in v2.2! SaaSavant includes 148 comprehensive tests covering all critical functionality. Run them locally or in CI/CD pipelines.

Overview

SaaSavant comes with a complete test suite that ensures all critical features work correctly:

  • 125 Unit Tests - Individual component and function testing
  • 23 Integration Tests - Complete user flow testing
  • E2E Tests - Browser-based UI testing with Playwright

Running Tests

Quick Start

# Run all tests in watch mode
npm test
 
# Press 'a' to run all tests

Test Commands

# Run all tests with coverage (CI mode)
npm run test:ci
 
# Run only unit tests
npm run test:unit
 
# Run only integration tests
npm run test:integration
 
# Run E2E tests with Playwright
npm run test:e2e
 
# Run E2E tests with Playwright UI (visual mode)
npm run test:e2e:ui

What's Tested

Authentication (27 tests)

  • ✅ Sign up flow with email/password
  • ✅ Sign in validation
  • ✅ Password reset functionality
  • ✅ User creation in Firestore
  • ✅ Error handling

Subscriptions (54 tests)

  • ✅ Stripe checkout session creation
  • ✅ Subscription lifecycle management
  • ✅ Payment success/failure handling
  • ✅ Subscription updates and cancellations
  • ✅ Premium status validation

Support System (16 tests)

  • ✅ Ticket creation
  • ✅ Ticket status updates
  • ✅ Ticket retrieval
  • ✅ Admin ticket management

Account Management (12 tests)

  • ✅ Account deletion
  • ✅ Data cleanup
  • ✅ Subscription cancellation on deletion

API Routes (16 tests)

  • ✅ Webhook event processing
  • ✅ Checkout endpoint
  • ✅ Portal endpoint
  • ✅ Email sending

Utilities (16 tests)

  • ✅ Stripe client functions
  • ✅ Premium status checker
  • ✅ Helper functions

Test Structure

__tests__/
├── unit/                    # Unit tests (125 tests)
│   ├── auth/               # Authentication tests
│   ├── subscriptions/      # Subscription tests
│   ├── support/            # Support ticket tests
│   ├── account/            # Account management tests
│   ├── api/                # API route tests
│   └── lib/                # Utility tests
├── integration/            # Integration tests (23 tests)
│   ├── auth-flow.test.tsx
│   └── subscription-flow.test.ts
├── e2e/                    # E2E tests (Playwright)
│   ├── auth.spec.ts
│   ├── subscription.spec.ts
│   └── support-tickets.spec.ts
├── mocks/                  # Test mocks
│   ├── firebase.ts
│   └── stripe.ts
└── utils/                  # Test utilities
    └── test-utils.tsx

Writing Tests

Unit Test Example

import { render, screen } from '@testing-library/react';
import SignUpForm from '@/components/user/SignUp';
 
describe('SignUpForm', () => {
  it('renders sign up form', () => {
    render(<SignUpForm />);
    expect(screen.getByText('Sign Up')).toBeInTheDocument();
  });
 
  it('validates email format', async () => {
    render(<SignUpForm />);
    // Test email validation
  });
});

Integration Test Example

describe('Authentication Flow', () => {
  it('completes full sign up and sign in flow', async () => {
    // 1. Sign up new user
    // 2. Verify user in Firestore
    // 3. Sign out
    // 4. Sign in with same credentials
    // 5. Verify authenticated state
  });
});

Test Configuration

Jest Configuration

Tests use Jest with the following setup:

  • Environment: jsdom (browser-like environment)
  • Transform: Next.js SWC compiler
  • Coverage: Enabled with thresholds
  • Mocks: Firebase and Stripe automatically mocked

Playwright Configuration

E2E tests use Playwright with:


Troubleshooting

Tests Failing

Check environment variables:

# Make sure .env.local is configured
cp .env.example .env.local

Clear Jest cache:

macOS/Linux:

npx jest --clearCache
npm test

Windows:

npx jest --clearCache
npm test

E2E Tests Failing

Install Playwright browsers:

npx playwright install

Run with UI mode for debugging:

npm run test:e2e:ui

Mock Issues

If Firebase or Stripe mocks aren't working:

  1. Check __tests__/mocks/firebase.ts
  2. Check __tests__/mocks/stripe.ts
  3. Verify jest.setup.js is loading mocks

Coverage Reports

After running npm run test:ci, view coverage:

macOS:

# Coverage report is in coverage/ directory
open coverage/lcov-report/index.html

Windows:

# Coverage report is in coverage/ directory
Start-Process coverage/lcov-report/index.html

Linux:

# Coverage report is in coverage/ directory
xdg-open coverage/lcov-report/index.html

Coverage Thresholds:

  • Branches: 70%
  • Functions: 70%
  • Lines: 70%
  • Statements: 70%

Best Practices

1. Test Behavior, Not Implementation

Bad:

expect(component.state.count).toBe(5);

Good:

expect(screen.getByText('Count: 5')).toBeInTheDocument();

2. Use Descriptive Test Names

Bad:

it('works', () => { ... });

Good:

it('creates checkout session with correct price ID', () => { ... });

3. Arrange, Act, Assert

it('updates subscription status', async () => {
  // Arrange
  const userId = 'test-user';
  const subscription = { status: 'active' };
  
  // Act
  await updateSubscription(userId, subscription);
  
  // Assert
  expect(mockFirestore.update).toHaveBeenCalledWith(...);
});

4. Clean Up After Tests

afterEach(() => {
  jest.clearAllMocks();
  cleanup();
});

Continuous Integration

Tests run automatically on:

  • Push to main or develop branches
  • Pull requests

Note: GitHub Actions CI/CD was removed in v2.2.1, but you can easily add it back by creating .github/workflows/ci.yml.


Additional Resources


🎉

Your tests are ready! Run npm test to start testing your application.