@company-manager/docs
Development

Tests

Guide complet des tests pour Company Manager.

Tests

Guide complet pour tester les applications Company Manager.

Configuration

Vitest

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
});

Setup

// src/test/setup.ts
import '@testing-library/jest-dom';
import { vi } from 'vitest';

// Mock des variables d'environnement
vi.mock('process.env', () => ({
  NEXT_PUBLIC_API_URL: 'http://localhost:3000',
}));

// Nettoyage après chaque test
afterEach(() => {
  vi.clearAllMocks();
});

Tests Unitaires

Composants React

import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';

describe('Button', () => {
  it('should render correctly', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });

  it('should handle click events', () => {
    const onClick = vi.fn();
    render(<Button onClick={onClick}>Click me</Button>);
    
    fireEvent.click(screen.getByText('Click me'));
    expect(onClick).toHaveBeenCalled();
  });
});

Hooks

import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';

describe('useCounter', () => {
  it('should increment counter', () => {
    const { result } = renderHook(() => useCounter());

    act(() => {
      result.current.increment();
    });

    expect(result.current.count).toBe(1);
  });
});

Services

import { UserService } from './UserService';

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    service = new UserService();
  });

  it('should fetch user by id', async () => {
    const user = await service.getUser('123');
    expect(user).toEqual(expect.objectContaining({
      id: '123',
      name: expect.any(String),
    }));
  });
});

Tests d'Intégration

API Routes

import { createMocks } from 'node-mocks-http';
import { handler } from './api/users';

describe('Users API', () => {
  it('should create user', async () => {
    const { req, res } = createMocks({
      method: 'POST',
      body: {
        name: 'John Doe',
        email: 'john@example.com',
      },
    });

    await handler(req, res);

    expect(res._getStatusCode()).toBe(201);
    expect(JSON.parse(res._getData())).toEqual(
      expect.objectContaining({
        id: expect.any(String),
      })
    );
  });
});

Base de Données

import { prisma } from '@/lib/prisma';

describe('Database Integration', () => {
  beforeEach(async () => {
    await prisma.user.deleteMany();
  });

  it('should create and retrieve user', async () => {
    const user = await prisma.user.create({
      data: {
        email: 'test@example.com',
        name: 'Test User',
      },
    });

    const found = await prisma.user.findUnique({
      where: { id: user.id },
    });

    expect(found).toEqual(user);
  });
});

Tests E2E

Playwright

import { test, expect } from '@playwright/test';

test('user flow', async ({ page }) => {
  // Login
  await page.goto('/login');
  await page.fill('[name=email]', 'user@example.com');
  await page.fill('[name=password]', 'password');
  await page.click('button[type=submit]');

  // Navigation
  await expect(page).toHaveURL('/dashboard');
  
  // Interaction
  await page.click('[data-testid=create-button]');
  await page.fill('[name=title]', 'New Item');
  await page.click('button[type=submit]');

  // Verification
  await expect(page.locator('h1')).toContainText('New Item');
});

Mocks

API Mocks

import { rest } from 'msw';
import { setupServer } from 'msw/node';

const server = setupServer(
  rest.get('/api/users', (req, res, ctx) => {
    return res(
      ctx.json([
        { id: '1', name: 'John' },
        { id: '2', name: 'Jane' },
      ])
    );
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

Component Mocks

vi.mock('@/components/Chart', () => ({
  Chart: () => <div data-testid="mocked-chart" />,
}));

Couverture de Tests

Configuration

// vitest.config.ts
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        'test/',
        '**/*.d.ts',
      ],
    },
  },
});

Scripts

{
  "scripts": {
    "test": "vitest",
    "test:coverage": "vitest run --coverage",
    "test:ui": "vitest --ui",
    "test:e2e": "playwright test"
  }
}

Bonnes Pratiques

  1. Organisation

    • Un fichier de test par module
    • Nommage clair et descriptif
    • Structure AAA (Arrange, Act, Assert)
  2. Performance

    • Isolation des tests
    • Nettoyage après chaque test
    • Utilisation de mocks appropriés
  3. Maintenabilité

    • Tests lisibles et maintenables
    • Éviter la duplication de code
    • Documentation des cas complexes