Skip to content
Testing Patterns logo

Testing Patterns

> **Skill Purpose:** API testing strategies, test automation patterns, and quality assurance procedures

Coverage-Creatives/zeus0installs0stars

SKILL.md

Full skill instructions

Testing Patterns

Skill Purpose: API testing strategies, test automation patterns, and quality assurance procedures


Core Skill Pattern

Objective: Establish comprehensive testing strategy with automated test suites, coverage requirements, and quality gates.

Universal Pattern:

  1. Define testing strategy and approach
  2. Create unit testing patterns and procedures
  3. Establish integration testing frameworks
  4. Set up E2E testing automation
  5. Create test coverage and reporting procedures

Key Decisions (Project-Specific):

  • Testing frameworks and tools
  • Test coverage requirements and thresholds
  • Testing environment setup and management
  • CI/​CD integration and automation
  • Test data management and fixtures

Project-Specific Implementation Notes

Customize per project:

  • Testing frameworks based on tech stack and team preferences
  • Coverage requirements based on criticality and standards
  • Test environment based on deployment complexity
  • Automation depth based on CI/​CD maturity
  • Test data strategy based on data complexity and privacy

Example Implementation (Next.js Testing Pattern)

Note: This is an example pattern using Jest, Vitest, and Playwright for Next.js. Adapt testing frameworks and patterns based on your specific project requirements and tech stack.

Prerequisites (Example)

  • Next.js project structure established
  • Testing frameworks selected and configured
  • Test environment and database setup
  • CI/​CD pipeline configured for automated testing

Example: API Testing Implementation

Framework-Specific Example: This demonstrates API testing patterns with Jest and Playwright. Adapt for your testing framework and API requirements.

Unit Testing Setup

// jest.config.js
const nextJest = require('next/​jest');

const createJestConfig = nextJest({
  dir: './',
});

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/​jest.setup.js'],
  moduleNameMapping: {
    '^@/(.*)$': '<rootDir>/​$1',
  },
  testEnvironment: 'jest-environment-jsdom',
  collectCoverageFrom: [
    'app/​**/​*.{js,jsx,ts,tsx}',
    'lib/​**/​*.{js,jsx,ts,tsx}',
    '!**/​*.d.ts',
    '!**/​node_modules/​**',
  ],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
};

module.exports = createJestConfig(customJestConfig);
// jest.setup.js
import '@testing-library/​jest-dom';

// Mock Supabase client
jest.mock('@/​lib/​supabase', () => ({
  supabase: {
    from: jest.fn(() => ({
      select: jest.fn(() => ({
        eq: jest.fn(() => ({
          single: jest.fn(() => ({
            data: null,
            error: null,
          })),
        })),
        insert: jest.fn(() => ({
          select: jest.fn(() => ({
            single: jest.fn(() => ({
              data: { id: 1, created_at: new Date().toISOString() },
              error: null,
            })),
          })),
        })),
      })),
    })),
  },
}));

// Global test utilities
global.testUser = {
  id: 'test-user-id',
  email: '[email protected]',
  name: 'Test User',
};

API Route Unit Tests

// __tests__/​api/​users.test.ts
import { createMocks } from 'node-mocks-http';
import { GET, POST } from '@/​app/​api/​users/​route';
import { supabase } from '@/​lib/​supabase';

// Mock Supabase
jest.mock('@/​lib/​supabase');
const mockSupabase = supabase as jest.Mocked<typeof supabase>;

describe('/​api/​users', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('GET', () => {
    it('should return users list', async () => {
      const mockUsers = [
        { id: 1, email: '[email protected]', name: 'User 1' },
        { id: 2, email: '[email protected]', name: 'User 2' },
      ];

      mockSupabase.from.mockReturnValue({
        select: jest.fn().mockReturnValue({
          eq: jest.fn().mockReturnValue({
            data: mockUsers,
            error: null,
          }),
        }),
      } as any);

      const { req } = createMocks({ method: 'GET' });
      const response = await GET(req);

      expect(response.status).toBe(200);
      const data = await response.json();
      expect(data.data).toEqual(mockUsers);
    });

    it('should handle database errors', async () => {
      mockSupabase.from.mockReturnValue({
        select: jest.fn().mockReturnValue({
          eq: jest.fn().mockReturnValue({
            data: null,
            error: new Error('Database error'),
          }),
        }),
      } as any);

      const { req } = createMocks({ method: 'GET' });
      const response = await GET(req);

      expect(response.status).toBe(500);
      const data = await response.json();
      expect(data.error).toBe('Internal server error');
    });
  });

  describe('POST', () => {
    it('should create a new user', async () => {
      const newUser = {
        email: '[email protected]',
        name: 'New User',
      };

      mockSupabase.from.mockReturnValue({
        insert: jest.fn().mockReturnValue({
          select: jest.fn().mockReturnValue({
            single: jest.fn().mockReturnValue({
              data: { id: 3, ...newUser, created_at: new Date().toISOString() },
              error: null,
            }),
          }),
        }),
      } as any);

      const { req } = createMocks({
        method: 'POST',
        body: newUser,
      });

      const response = await POST(req);

      expect(response.status).toBe(201);
      const data = await response.json();
      expect(data.data.email).toBe(newUser.email);
      expect(data.data.name).toBe(newUser.name);
    });

    it('should validate required fields', async () => {
      const invalidUser = {
        name: 'Invalid User',
        // Missing email
      };

      const { req } = createMocks({
        method: 'POST',
        body: invalidUser,
      });

      const response = await POST(req);

      expect(response.status).toBe(400);
      const data = await response.json();
      expect(data.error).toContain('Email is required');
    });
  });
});

Integration Testing

// __tests__/​integration/​user-workflow.test.ts
import { createMocks } from 'node-mocks-http';
import { GET as getUser } from '@/​app/​api/​users/[id]/​route';
import { POST as createUser } from '@/​app/​api/​users/​route';
import { supabase } from '@/​lib/​supabase';

jest.mock('@/​lib/​supabase');
const mockSupabase = supabase as jest.Mocked<typeof supabase>;

describe('User Workflow Integration', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('should complete user creation and retrieval workflow', async () => {
    const userData = {
      email: '[email protected]',
      name: 'Workflow User',
    };

    const createdUser = {
      id: 999,
      ...userData,
      created_at: new Date().toISOString(),
    };

    // Mock user creation
    mockSupabase.from.mockReturnValue({
      insert: jest.fn().mockReturnValue({
        select: jest.fn().mockReturnValue({
          single: jest.fn().mockReturnValue({
            data: createdUser,
            error: null,
          }),
        }),
      }),
    } as any);

    // Create user
    const { req: createReq } = createMocks({
      method: 'POST',
      body: userData,
    });

    const createResponse = await createUser(createReq);
    expect(createResponse.status).toBe(201);

    // Mock user retrieval
    mockSupabase.from.mockReturnValue({
      select: jest.fn().mockReturnValue({
        eq: jest.fn().mockReturnValue({
          single: jest.fn().mockReturnValue({
            data: createdUser,
            error: null,
          }),
        }),
      }),
    } as any);

    // Retrieve user
    const { req: getReq } = createMocks({
      method: 'GET',
      query: { id: '999' },
    });

    const getResponse = await getUser(getReq);
    expect(getResponse.status).toBe(200);

    const retrievedData = await getResponse.json();
    expect(retrievedData.data.email).toBe(userData.email);
  });
});

E2E Testing with Playwright

// e2e/​api-testing.spec.ts
import { test, expect } from '@playwright/​test';

test.describe('API E2E Tests', () => {
  test.beforeEach(async ({ request }) => {
    // Setup test data or authentication
  });

  test('should handle complete user lifecycle', async ({ request }) => {
    // Create user
    const createUserResponse = await request.post('/​api/​users', {
      data: {
        email: '[email protected]',
        name: 'E2E Test User',
      },
    });

    expect(createUserResponse.ok()).toBeTruthy();
    const createdUser = await createUserResponse.json();
    const userId = createdUser.data.id;

    // Get user
    const getUserResponse = await request.get(`/​api/​users/​${userId}`);
    expect(getUserResponse.ok()).toBeTruthy();

    const retrievedUser = await getUserResponse.json();
    expect(retrievedUser.data.email).toBe('[email protected]');

    // Update user (if endpoint exists)
    const updateUserResponse = await request.put(`/​api/​users/​${userId}`, {
      data: {
        name: 'Updated E2E User',
      },
    });

    expect(updateUserResponse.ok()).toBeTruthy();

    // Delete user (if endpoint exists)
    const deleteUserResponse = await request.delete(`/​api/​users/​${userId}`);
    expect(deleteUserResponse.ok()).toBeTruthy();
  });

  test('should handle authentication flows', async ({ request }) => {
    // Test login
    const loginResponse = await request.post('/​api/​auth/​login', {
      data: {
        email: '[email protected]',
        password: 'testpassword',
      },
    });

    expect(loginResponse.ok()).toBeTruthy();
    const loginData = await loginResponse.json();
    expect(loginData.token).toBeDefined();

    // Use token for authenticated request
    const protectedResponse = await request.get('/​api/​protected', {
      headers: {
        Authorization: `Bearer ${loginData.token}`,
      },
    });

    expect(protectedResponse.ok()).toBeTruthy();
  });

  test('should handle error scenarios', async ({ request }) => {
    // Test 404 for non-existent user
    const notFoundResponse = await request.get('/​api/​users/​99999');
    expect(notFoundResponse.status()).toBe(404);

    // Test validation errors
    const validationResponse = await request.post('/​api/​users', {
      data: {
        name: 'Invalid User',
        // Missing required email
      },
    });

    expect(validationResponse.status()).toBe(400);
    const validationData = await validationResponse.json();
    expect(validationData.error).toContain('required');
  });
});

Test Data Management

// __tests__/​utils/​test-data.ts
export class TestDataFactory {
  static createUser(overrides?: Partial<User>): User {
    return {
      id: Math.floor(Math.random() * 10000),
      email: `test-${Date.now()}@example.com`,
      name: 'Test User',
      created_at: new Date().toISOString(),
      ...overrides,
    };
  }

  static createUsers(count: number): User[] {
    return Array.from({ length: count }, () => this.createUser());
  }

  static createApiRequest(overrides?: Partial<ApiRequest>): ApiRequest {
    return {
      method: 'GET',
      headers: {
        'Content-Type': 'application/​json',
      },
      body: null,
      ...overrides,
    };
  }
}

// __tests__/​utils/​test-helpers.ts
export class TestHelpers {
  static async setupTestDatabase(): Promise<void> {
    // Setup test database with fixtures
    // This could involve running migrations, seeding data, etc.
  }

  static async cleanupTestDatabase(): Promise<void> {
    // Clean up test data after tests
  }

  static mockSupabaseResponse(data: any, error: Error | null = null) {
    return {
      data,
      error,
      count: data?.length || 0,
    };
  }
}

Performance Testing

// __tests__/​performance/​api-load.test.ts
import { test, expect } from '@playwright/​test';

test.describe('API Load Testing', () => {
  test('should handle concurrent requests', async ({ request }) => {
    const concurrentRequests = 50;
    const promises = Array.from({ length: concurrentRequests }, () =>
      request.get('/​api/​users')
    );

    const responses = await Promise.all(promises);
    
    // All requests should succeed
    responses.forEach(response => {
      expect(response.ok()).toBeTruthy();
    });

    // Response times should be reasonable
    const responseTimes = responses.map(response => 
      response.headers()['x-response-time']
    );
    
    const avgResponseTime = responseTimes.reduce(
      (sum, time) => sum + parseInt(time), 0
    ) / responseTimes.length;

    expect(avgResponseTime).toBeLessThan(1000); // Less than 1 second average
  });
});

Best Practices

  1. Test pyramid - More unit tests, fewer E2E tests for faster feedback
  2. Test isolation - Each test should be independent and not affect others
  3. Mock external dependencies - Use mocks for databases, APIs, and services
  4. Coverage requirements - Maintain high test coverage for critical paths
  5. Continuous testing - Integrate tests into CI/​CD pipeline for automated validation

Stop Conditions

STOP and escalate if:

  • Testing strategy unclear or incomplete
  • Test environment not properly configured
  • Coverage requirements not defined
  • Test data management strategy missing

Skill Version: 1.0.0

More skills from Coverage-Creatives

Zod Validation logo
Coverage-Creatives/zeus

Zod Validation

> **Skill Purpose:** TypeScript-first schema validation and runtime type checking patterns

0 0
View
Schema Trace logo
Coverage-Creatives/zeus

Schema Trace

> **Skill Purpose:** Database schema alignment and data flow verification patterns

0 0
View
Security Scanning logo
Coverage-Creatives/zeus

Security Scanning

> **Skill Purpose:** API security assessment, vulnerability scanning, and security validation procedures

0 0
View
Baseline Management logo
Coverage-Creatives/zeus

Baseline Management

> **Skill Purpose:** Maintain baselines for regression, performance, and snapshot tests to detect meaningful changes.

0 0
View
Auth Locked logo
Coverage-Creatives/zeus

Auth Locked

> **Skill Purpose:** Authentication and authorization security patterns with access control

0 0
View
Supabase Client Setup logo
Coverage-Creatives/zeus

Supabase Client Setup

> **Skill Purpose:** Backend-as-a-Service client integration and configuration patterns

0 0
View
Environment Management logo
Coverage-Creatives/zeus

Environment Management

> **Skill Purpose:** Multi-environment configuration and deployment patterns

0 0
View
Responsive Design logo
Coverage-Creatives/zeus

Responsive Design

> **Skill Purpose:** Mobile-first design implementation, breakpoint management, and responsive component patterns

0 0
View
Penetration Testing logo
Coverage-Creatives/zeus

Penetration Testing

> **Skill Purpose:** Plan and execute authorized penetration testing to identify exploitable security weaknesses.

0 0
View
Tailwind CSS Setup logo
Coverage-Creatives/zeus

Tailwind CSS Setup

> **Skill Purpose:** CSS framework configuration and styling system patterns

0 0
View
Pre-Commit Hooks logo
Coverage-Creatives/zeus

Pre-Commit Hooks

> **Skill Purpose:** Establish code quality enforcement patterns before commits

0 0
View
Performance Monitoring logo
Coverage-Creatives/zeus

Performance Monitoring

> **Skill Purpose:** Instrument and monitor application performance with metrics, alerts, and trend analysis.

0 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View