Tests unitaires et d’intégration pour le frontend en 2026

RÉSUMÉ

Maîtriser les tests unitaires et d’intégration en 2026

Guide complet pour des applications frontend robustes et fiables avec les meilleures pratiques.

Keywords: Tests Frontend, Tests Unitaires, Tests d’Intégration

TABLE DES MATIÈRES

1 Contexte et Importance des Tests Frontend en 2026

2 Tests Unitaires : Les Fondations de la Qualité avec Jest

3 Tests d’Intégration : Simuler l’Expérience Utilisateur avec React Testing Library

4 Au-delà de l’Intégration : Vue d’Ensemble des Tests E2E avec Cypress

5 Stratégies Avancées et Meilleures Pratiques pour des Tests Frontend Robustes

6 Résolution des Défis Communs en Tests Frontend

7 Mise en Œuvre Pratique : Configuration et Premier Test

8 Foire Aux Questions

INTRODUCTION

Contexte et Importance des Tests Frontend en 2026

Dans le paysage numérique en constante évolution de 2026, la qualité et la fiabilité des applications frontend sont plus cruciales que jamais. Pour maîtriser les tests unitaires et d’intégration, les développeurs doivent adopter des méthodologies et des outils modernes qui garantissent non seulement la fonctionnalité, mais aussi une expérience utilisateur irréprochable. Ce guide complet explore les meilleures pratiques et les outils incontournables tels que Jest, React Testing Library et Cypress, essentiels pour construire des applications frontend robustes et maintenables.

La complexité croissante des interfaces utilisateur, l’omniprésence des frameworks JavaScript comme React, Angular et Vue.js, et les attentes élevées des utilisateurs exigent une stratégie de test rigoureuse. Les bugs dans le frontend peuvent avoir un impact direct et significatif sur la réputation d’une entreprise et sur la satisfaction client. Selon une étude de Gartner de 2025, les applications web avec une couverture de test supérieure à 70% affichent une réduction de 45% des incidents de production critiques, soulignant l’investissement justifié dans le testing.

« Un code non testé est un code cassé qui n’attend que le bon moment pour échouer en production. »

— Kwontenu, Expert en Qualité Logicielle

Les tests unitaires et d’intégration sont les piliers de cette stratégie. Les premiers se concentrent sur la vérification des plus petites unités de code de manière isolée, tandis que les seconds s’assurent que différentes unités fonctionnent correctement ensemble, souvent en simulant les interactions utilisateur. En combinant ces approches avec des outils performants, les équipes de développement peuvent détecter les problèmes tôt dans le cycle de vie, réduire les coûts de correction et accélérer la livraison de nouvelles fonctionnalités avec confiance.

POINT CLÉ

L’adoption d’une stratégie de tests robuste dès 2026 est non seulement une bonne pratique, mais une nécessité pour la compétitivité et la fiabilité des applications frontend. Elle permet de détecter les défauts précocement, réduisant les coûts de maintenance et améliorant la confiance dans le déploiement.


TESTS UNITAIRES

Tests Unitaires : Les Fondations de la Qualité avec Jest

Les tests unitaires sont la première ligne de défense contre les bugs. Ils consistent à tester les plus petites parties isolées de votre code, comme des fonctions pures, des méthodes de classe ou des composants sans état. L’objectif est de s’assurer que chaque unité fonctionne comme prévu, indépendamment du reste du système. En frontend, cela signifie tester des fonctions utilitaires, des réducteurs Redux, des hooks personnalisés ou de petits composants React/Vue/Angular.

Pour le testing unitaire en JavaScript, Jest s’est imposé comme le framework de facto. Développé par Facebook, il est rapide, facile à configurer et offre une riche API d’assertions, de mocks et de snapshots. Sa popularité repose sur son approche « batteries-included », qui simplifie grandement la mise en place d’une suite de tests.

Pourquoi Jest ?

Simplicité — Configuration minimale, souvent prête à l’emploi avec create-react-app ou Vue CLI.

Performance — Exécution rapide des tests en parallèle, avec un cache intelligent.

Fonctionnalités Riches — Assertions intégrées, mocks puissants, tests de snapshot, coverage report.

Communauté — Large support et documentation, mises à jour régulières.

Exemple de Test Unitaire avec Jest

Considérons une simple fonction utilitaire qui formate une date. L’objectif est de vérifier que cette fonction retourne le format attendu pour différentes entrées.

EXPLICATION DU CODE

Cette fonction formatDate prend une date en paramètre et la formate en « JJ/MM/AAAA ». Le test unitaire vérifie qu’elle fonctionne correctement pour une date donnée.

// src/utils/dateFormatter.js
export function formatDate(dateString) {
  if (!dateString) return '';
  const date = new Date(dateString);
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0'); // Mois est basé sur 0
  const year = date.getFullYear();
  return `${day}/${month}/${year}`;
}

// src/utils/__tests__/dateFormatter.test.js
import { formatDate } from '../dateFormatter';

describe('formatDate', () => {
  test('devrait formater une date valide au format JJ/MM/AAAA', () => {
    const date = '2026-05-16T10:00:00Z';
    expect(formatDate(date)).toBe('16/05/2026');
  });

  test('devrait retourner une chaîne vide pour une date nulle ou indéfinie', () => {
    expect(formatDate(null)).toBe('');
    expect(formatDate(undefined)).toBe('');
  });

  test('devrait gérer les dates avec un seul chiffre pour le jour ou le mois', () => {
    const date = '2026-01-01T10:00:00Z';
    expect(formatDate(date)).toBe('01/01/2026');
  });
});

Ces tests unitaires sont rapides à exécuter et fournissent un feedback immédiat sur la correction de la fonction formatDate. Ils sont essentiels pour s’assurer que chaque brique de votre application fonctionne de manière isolée avant d’être assemblée avec d’autres.

Illustration d'une unité de code testée en isolation


TESTS D’INTÉGRATION

Tests d’Intégration : Simuler l’Expérience Utilisateur avec React Testing Library

Alors que les tests unitaires valident des parties isolées, les tests d’intégration vérifient que ces unités fonctionnent correctement lorsqu’elles sont combinées. En frontend, cela prend souvent la forme de tests de composants qui interagissent avec d’autres composants, des hooks, ou des APIs, en se concentrant sur le comportement de l’utilisateur. L’objectif n’est pas de tester les détails d’implémentation, mais plutôt l’expérience utilisateur finale. Si un utilisateur peut cliquer sur un bouton et voir un résultat attendu, le test est réussi.

Pour les applications React, React Testing Library (RTL) est l’outil recommandé. Contrairement à des bibliothèques plus anciennes qui encourageaient les tests d’implémentation (par exemple, tester l’état interne d’un composant), RTL promeut des tests axés sur le comportement utilisateur. Il fournit des utilitaires qui permettent de rechercher des éléments DOM de la même manière qu’un utilisateur les trouverait (par leur texte, leur rôle d’accessibilité, etc.) et de simuler des événements utilisateur.

« La meilleure manière de tester un composant est de l’utiliser comme un utilisateur. »

— Kent C. Dodds, Créateur de Testing Library

Exemple de Test d’Intégration avec React Testing Library

Imaginons un composant de formulaire simple qui affiche un message de succès après une soumission valide. Nous voulons nous assurer que l’utilisateur peut interagir avec le formulaire et que le message correct apparaît.

EXPLICATION DU CODE

Le composant ContactForm gère un champ de saisie et un bouton de soumission. Le test RTL simule la saisie de texte et le clic sur le bouton, puis vérifie que le message de succès apparaît.

// src/components/ContactForm.jsx
import React, { useState } from 'react';

function ContactForm() {
  const [name, setName] = useState('');
  const [submitted, setSubmitted] = useState(false);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (name) {
      // Simuler un appel API
      setTimeout(() => {
        setSubmitted(true);
      }, 100);
    }
  };

  if (submitted) {
    return <div data-testid="success-message">Merci, {name} ! Votre message a été envoyé.</div>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name-input">Nom :</label>
      <input
        id="name-input"
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Votre nom"
      />
      <button type="submit" disabled={!name}>Envoyer</button>
    </form>
  );
}

export default ContactForm;

// src/components/__tests__/ContactForm.test.jsx
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import ContactForm from '../ContactForm';
import '@testing-library/jest-dom'; // Pour les matchers Jest-DOM

describe('ContactForm', () => {
  test('devrait afficher un message de succès après la soumission', async () => {
    render(<ContactForm />);

    // Trouver l'input par son rôle ou son label
    const nameInput = screen.getByLabelText(/Nom :/i);
    fireEvent.change(nameInput, { target: { value: 'Kwontenu' } });

    // Trouver le bouton par son rôle
    const submitButton = screen.getByRole('button', { name: /Envoyer/i });
    fireEvent.click(submitButton);

    // Attendre que le message de succès apparaisse (simule un appel asynchrone)
    await waitFor(() => {
      expect(screen.getByTestId('success-message')).toHaveTextContent('Merci, Kwontenu ! Votre message a été envoyé.');
    });

    // Vérifier que le formulaire n'est plus visible
    expect(screen.queryByRole('form')).not.toBeInTheDocument();
  });

  test('le bouton Envoyer devrait être désactivé sans nom', () => {
    render(<ContactForm />);
    const submitButton = screen.getByRole('button', { name: /Envoyer/i });
    expect(submitButton).toBeDisabled();
  });

  test('le bouton Envoyer devrait être activé avec un nom', () => {
    render(<ContactForm />);
    const nameInput = screen.getByLabelText(/Nom :/i);
    fireEvent.change(nameInput, { target: { value: 'Test User' } });
    const submitButton = screen.getByRole('button', { name: /Envoyer/i });
    expect(submitButton).not.toBeDisabled();
  });
});

Ce test simule une interaction utilisateur complète, du remplissage du champ à la soumission du formulaire, en passant par l’attente d’un événement asynchrone. Il garantit que le flux utilisateur critique fonctionne comme prévu, ce qui est l’essence même des tests d’intégration centrés sur l’utilisateur.

POINT CLÉ

React Testing Library est un outil puissant pour les tests d’intégration frontend car il encourage les tests qui reflètent la manière dont les utilisateurs interagissent avec votre application, plutôt que de se concentrer sur les détails d’implémentation. Cela conduit à des tests plus robustes et moins fragiles face aux refactorisations internes.

Diagramme montrant comment React Testing Library interagit avec le rendu d'un composant


TESTS E2E

Au-delà de l’Intégration : Vue d’Ensemble des Tests E2E avec Cypress

Si les tests unitaires et d’intégration couvrent des aspects essentiels de votre code et de vos composants, les tests de bout en bout (End-to-End ou E2E) vont plus loin. Ils simulent des scénarios utilisateur complets, de la connexion à la soumission de données complexes, en passant par l’interaction avec des services backend réels ou simulés, et ce, dans un navigateur réel. L’objectif est de valider l’ensemble de la chaîne de valeur de l’application, du frontend au backend et à la base de données.

Pour les tests E2E en frontend, Cypress est devenu un choix prédominant. Il offre une expérience de développement de tests rapide et fiable, avec un tableau de bord interactif, des rechargements à chaud, et la capacité de voyager dans le temps pour déboguer les étapes des tests. Contrairement à Selenium, Cypress s’exécute directement dans le navigateur, ce qui permet un débogage plus facile et des tests plus stables.

AVERTISSEMENT

Bien que les tests E2E soient cruciaux, ils sont plus lents et plus coûteux à maintenir que les tests unitaires et d’intégration. Ce guide se concentre principalement sur les tests unitaires et d’intégration. Une couverture E2E complète nécessiterait un article dédié, mais il est important de comprendre leur rôle dans une stratégie de test globale.

Principes des Tests E2E avec Cypress

Un test E2E avec Cypress simulerait un utilisateur naviguant sur votre site, remplissant des formulaires, cliquant sur des liens, et vérifiant que l’interface utilisateur réagit comme attendu, y compris les appels réseau vers le backend. C’est le niveau de test le plus proche de l’expérience utilisateur réelle.

EXPLICATION DU CODE

Cet exemple Cypress simule la visite d’une page de connexion, la saisie d’informations d’identification et la vérification de la redirection vers un tableau de bord. Il teste l’intégration complète du frontend, du backend et de la navigation.

// cypress/e2e/login.cy.js
describe('Scénario de connexion utilisateur', () => {
  it('devrait permettre à un utilisateur de se connecter et d\'accéder au tableau de bord', () => {
    // Visiter la page de connexion
    cy.visit('https://kwontenu.com/login');

    // Intercepter les requêtes API pour les mocker si nécessaire
    cy.intercept('POST', '/api/login', {
      statusCode: 200,
      body: { token: 'fake-jwt-token', user: { id: 1, username: 'testuser' } },
    }).as('loginRequest');

    // Saisir l'identifiant et le mot de passe
    cy.get('input[name="username"]').type('utilisateur_test');
    cy.get('input[name="password"]').type('motdepasse_secret');

    // Cliquer sur le bouton de connexion
    cy.get('button[type="submit"]').click();

    // Attendre la réponse de l'API de connexion
    cy.wait('@loginRequest');

    // Vérifier que l'utilisateur est redirigé vers le tableau de bord
    cy.url().should('include', '/dashboard');
    cy.get('h1').should('contain', 'Bienvenue sur votre tableau de bord');
  });

  it('devrait afficher une erreur pour des informations d\'identification invalides', () => {
    cy.visit('https://kwontenu.com/login');

    cy.intercept('POST', '/api/login', {
      statusCode: 401,
      body: { message: 'Identifiants invalides' },
    }).as('failedLoginRequest');

    cy.get('input[name="username"]').type('mauvais_utilisateur');
    cy.get('input[name="password"]').type('mauvais_motdepasse');
    cy.get('button[type="submit"]').click();

    cy.wait('@failedLoginRequest');
    cy.get('[data-testid="error-message"]').should('contain', 'Identifiants invalides');
  });
});

Cypress permet de simuler des scénarios complexes et de vérifier la robustesse de l’application dans son ensemble. C’est un outil indispensable pour garantir que les flux utilisateurs critiques fonctionnent parfaitement en production.

POINT CLÉ

Cypress offre une solution puissante pour les tests E2E en simulant des interactions utilisateur réelles dans un navigateur. Il est idéal pour valider les parcours critiques des utilisateurs et l’intégration de l’ensemble de la pile technologique, complétant ainsi la pyramide des tests.

Capture d'écran de l'interface de Cypress affichant un test E2E réussi


STRATÉGIES

Stratégies Avancées et Meilleures Pratiques pour des Tests Frontend Robustes

Pour une stratégie de test frontend efficace en 2026, il ne suffit pas de choisir les bons outils ; il faut aussi adopter les bonnes pratiques. La pyramide des tests, bien que souvent débattue, reste un modèle pertinent pour équilibrer les différents types de tests et optimiser les efforts.

« La pyramide des tests nous rappelle que la plupart de nos tests devraient être unitaires, un nombre significatif d’intégration, et seulement quelques-uns de bout en bout. »

— Martin Fowler

La Pyramide des Tests

La pyramide des tests suggère que vous devriez avoir beaucoup de tests unitaires (rapides et peu coûteux), un nombre modéré de tests d’intégration (un peu plus lents et plus coûteux), et un petit nombre de tests E2E (les plus lents et les plus coûteux). Cela garantit une couverture maximale avec un coût de maintenance minimal.

Optimisation de la Pyramide

Tests Unitaires (Base) — Couvrent 70-80% du code. Ciblent les fonctions pures, les utilitaires, les réducteurs. Exécutent en millisecondes.

Tests d’Intégration (Milieu) — Couvrent 15-25% du code. Ciblent les interactions entre composants, l’intégration avec des APIs mockées. Exécutent en secondes.

Tests E2E (Sommet) — Couvrent 5-10% des chemins critiques. Ciblent les flux utilisateur complets, l’intégration système. Exécutent en minutes.

Mocking et Stubbing

Dans les tests unitaires et d’intégration, il est fréquent de devoir isoler la partie du code testée des dépendances externes (appels API, base de données, modules tiers). C’est là que le mocking et le stubbing entrent en jeu :

  • Mocks : Objets simulés qui enregistrent les interactions. Utiles pour vérifier qu’une fonction a été appelée avec les bons arguments. Jest offre des fonctions jest.fn() et jest.mock() pour cela.
  • Stubs : Objets simulés qui fournissent des réponses prédéfinies à des appels de méthode. Utiles pour contrôler le comportement d’une dépendance.

Par exemple, pour tester un composant qui effectue un appel API, vous « mockeriez » l’appel fetch ou axios pour qu’il retourne des données factices, évitant ainsi de dépendre d’un serveur réel.

EXPLICATION DU CODE

Cet exemple montre comment utiliser jest.fn() pour mocker une fonction de service et vérifier qu’elle est appelée correctement par un composant.

// src/services/apiService.js
export const fetchUserData = async (userId) => {
  const response = await fetch(`https://api.example.com/users/${userId}`);
  return response.json();
};

// src/components/UserProfile.jsx
import React, { useEffect, useState } from 'react';
import { fetchUserData } from '../services/apiService';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const loadUser = async () => {
      setLoading(true);
      const data = await fetchUserData(userId);
      setUser(data);
      setLoading(false);
    };
    loadUser();
  }, [userId]);

  if (loading) return <div>Chargement du profil...</div>;
  if (!user) return <div>Utilisateur introuvable.</div>;

  return (
    <div>
      <h2>Profil de {user.name}</h2>
      <p>Email: {user.email}</p>
    </div>
  );
}

export default UserProfile;

// src/components/__tests__/UserProfile.test.jsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import UserProfile from '../UserProfile';
import { fetchUserData } from '../../services/apiService';

jest.mock('../../services/apiService'); // Mock le module apiService

describe('UserProfile', () => {
  beforeEach(() => {
    // Réinitialiser le mock avant chaque test
    fetchUserData.mockClear();
  });

  test('devrait afficher les informations de l\'utilisateur après le chargement', async () => {
    // Définir la valeur de retour du mock
    fetchUserData.mockResolvedValueOnce({ name: 'Jane Doe', email: '[email protected]' });

    render(<UserProfile userId="123" />);

    expect(screen.getByText('Chargement du profil...')).toBeInTheDocument();

    await waitFor(() => {
      expect(screen.getByText('Profil de Jane Doe')).toBeInTheDocument();
    });

    expect(screen.getByText('Email: [email protected]')).toBeInTheDocument();
    expect(fetchUserData).toHaveBeenCalledTimes(1);
    expect(fetchUserData).toHaveBeenCalledWith('123');
  });

  test('devrait afficher un message si l\'utilisateur est introuvable', async () => {
    fetchUserData.mockResolvedValueOnce(null); // Simuler un utilisateur non trouvé

    render(<UserProfile userId="456" />);

    await waitFor(() => {
      expect(screen.getByText('Utilisateur introuvable.')).toBeInTheDocument();
    });
    expect(fetchUserData).toHaveBeenCalledWith('456');
  });
});

Couverture de Code et Intégration CI/CD

La mesure de la couverture de code (code coverage) est un indicateur clé de la qualité de votre suite de tests. Des outils comme Istanbul (intégré à Jest) peuvent générer des rapports détaillés sur les lignes, les branches, les fonctions et les déclarations couvertes par vos tests. Un objectif de couverture de 80% est souvent considéré comme un bon point de départ, mais ne doit pas être une fin en soi.

L’intégration continue/déploiement continu (CI/CD) est l’étape finale pour automatiser l’exécution de vos tests. Chaque fois qu’un développeur pousse du code, la pipeline CI/CD doit exécuter l’ensemble de la suite de tests (unitaires, intégration, E2E). Si un test échoue, le build est cassé, empêchant l’intégration de code défectueux dans la branche principale. Des plateformes comme GitHub Actions, GitLab CI/CD ou Jenkins sont couramment utilisées pour cela.

POINT CLÉ

Une stratégie de test efficace combine la pyramide des tests, l’utilisation judicieuse des mocks/stubs et l’automatisation via CI/CD. La couverture de code est un indicateur utile, mais la qualité des tests et leur pertinence par rapport aux scénarios utilisateur sont primordiales.

Illustration d'un pipeline CI/CD avec les étapes de test


RÉSOLUTION DE PROBLÈMES

Résolution des Défis Communs en Tests Frontend

Même avec les meilleurs outils et pratiques, le testing frontend peut présenter des défis. Voici quelques problèmes courants et leurs solutions, basées sur l’expérience en 2026.

PROBLÈME 01

Gestion des Opérations Asynchrones

Les opérations asynchrones (appels API, timers, etc.) peuvent rendre les tests non déterministes et difficiles à déboguer. Les tests peuvent passer ou échouer de manière aléatoire en fonction du timing.

SOLUTION — Utiliser async/await et les utilitaires de la testing library

// Exemple avec React Testing Library
test('devrait charger les données après un appel API', async () => {
  // Mock l'appel API (fetch ou axios)
  jest.spyOn(global, 'fetch').mockResolvedValueOnce({
    json: () => Promise.resolve({ data: 'Données chargées' }),
  });

  render(<MyComponentThatFetchesData />);

  // Utiliser findBy* pour attendre l'apparition d'éléments asynchrones
  const loadedElement = await screen.findByText(/Données chargées/i);
  expect(loadedElement).toBeInTheDocument();

  // Restaurer le mock
  global.fetch.mockRestore();
});

PROBLÈME 02

Tests Fragiles (Flaky Tests)

Des tests qui échouent parfois sans raison apparente sont des « flaky tests ». Ils sapent la confiance dans la suite de tests et peuvent être causés par des dépendances externes non mockées, des problèmes de timing ou des dépendances à l’environment.

SOLUTION — Isoler les tests et utiliser des mocks fiables

// Utiliser des mocks pour toutes les dépendances externes
// Éviter les dépendances à l'ordre d'exécution des tests avec beforeEach/afterEach
describe('Mon Composant', () => {
  let mockService;
  beforeEach(() => {
    mockService = jest.fn(() => Promise.resolve('Données'));
    // Injecter le mock dans le composant ou mocker globalement
    jest.mock('../myService', () => ({
      __esModule: true,
      default: mockService,
    }));
  });

  afterEach(() => {
    jest.clearAllMocks(); // Nettoyer les mocks après chaque test
  });

  test('devrait bien se comporter avec le service mocké', async () => {
    // ... test du composant
  });
});

PROBLÈME 03

Configuration Complexe de l’Environnement de Test

La configuration des bundlers (Webpack, Vite), des transpileurs (Babel, TypeScript) et des frameworks de test peut être décourageante et chronophage.

SOLUTION — Utiliser des outils intégrés ou des préréglages

// Pour Jest avec React et TypeScript, utiliser ts-jest et les presets
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy', // Gérer les imports CSS
  },
};

// Pour Cypress, la configuration est souvent minimale et se fait via cypress.config.js
// ou directement dans les fichiers de test.

POINT CLÉ

Anticiper et adresser les défis courants du testing est essentiel pour maintenir une suite de tests saine. L’isolement des tests, la gestion rigoureuse des dépendances asynchrones et l’utilisation de configurations simplifiées sont des approches clés en 2026.

Organigramme des défis de test courants et de leurs solutions


APPLICATION PRATIQUE

Mise en Œuvre Pratique : Configuration et Premier Test

Pour concrétiser les concepts abordés, suivons les étapes pour configurer Jest et React Testing Library dans un projet React typique en 2026. Nous partirons d’un projet créé avec Vite, un bundler moderne et rapide.

1

Initialisation du Projet React avec Vite

Si vous n’avez pas encore de projet, créez-en un nouveau avec Vite. Cela configurera un environnement de développement React moderne.

EXPLICATION DU CODE

Ces commandes créent un nouveau projet React avec Vite et installent les dépendances initiales.

npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install

2

Installation de Jest et React Testing Library

Installez les dépendances nécessaires pour Jest et React Testing Library. jsdom est un environnement de test qui simule un navigateur DOM.

EXPLICATION DU CODE

Ces commandes installent Jest, les utilitaires de test pour React, l’environnement JSDOM et le package jest-environment-jsdom.

npm install --save-dev jest @testing-library/react @testing-library/jest-dom @babel/preset-env @babel/preset-react babel-jest jest-environment-jsdom

3

Configuration de Jest et Babel

Créez un fichier jest.config.js à la racine de votre projet et un fichier babel.config.js. Ces fichiers indiqueront à Jest comment exécuter les tests et à Babel comment transpiler le code React/ESM.

EXPLICATION DU CODE

Le fichier jest.config.js configure l’environnement de test et les fichiers de setup. Le fichier babel.config.js permet à Jest de comprendre la syntaxe JSX et ES Modules.

// jest.config.js
module.exports = {
  testEnvironment: 'jest-environment-jsdom',
  setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
  transform: {
    '^.+\\.(js|jsx)$': 'babel-jest',
  },
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  },
};

// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
    ['@babel/preset-react', { runtime: 'automatic' }],
  ],
};

// setupTests.js (à la racine du projet)
import '@testing-library/jest-dom';

4

Ajout du Script de Test

Mettez à jour votre fichier package.json pour inclure un script de test qui exécute Jest.

EXPLICATION DU CODE

Ajoutez cette ligne dans la section "scripts" de votre package.json.

// package.json
{
"name": "my-react-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"test": "jest" // <-- Ajoutez cette ligne
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/preset-env": "^7.24.0",
"@babel/preset-react": "^7.23.3",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.0",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-react": "^4.2.1",
"babel-jest": "^29.7.0",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.