Pourquoi Tester Next.js avec Jest ?
Dans un monde où les applications web sont devenues plus complexes, la qualité et la fiabilité deviennent des priorités essentielles. Lorsqu'il s'agit de tester une application basée sur Next.js, Jest est l'un des outils les plus populaires et efficaces. Jest permet aux développeurs d'écrire des tests unitaires, d'intégration et d'end-to-end pour leurs composants React, pages, API routes et autres éléments du projet.
Un cas concret de ce qui pourrait être un test utile est de vérifier que la navigation entre les différentes pages d'une application Next.js fonctionne correctement. Par exemple, si vous avez une page about qui redirige vers une page contact, il serait crucial de s'assurer que le navigateur effectue cette redirection sans erreurs.
Prerequis
Pour suivre ce tutoriel et tester un projet Next.js avec Jest, vous aurez besoin des éléments suivants :
- Node.js (v12 ou plus récent) : Jest nécessite Node.js pour exécuter les tests.
- Installation via npm :
npm install -g node
- Installation via npm :
- npm (v6 ou plus récent) : Utilisé pour gérer les dépendances du projet.
- Installation via npm :
npm install -g npm
- Installation via npm :
- Next.js : Créer un nouveau projet Next.js est simple avec la commande suivante :
- Initialisation d'un nouveau projet :
npx create-next-app@latest my-nextjs-app cd my-nextjs-app
- Initialisation d'un nouveau projet :
- Jest : Installer Jest comme dépendance de développement dans votre projet.
- Installation via npm :
npm install --save-dev jest
- Installation via npm :
Concepts fondamentaux
Test React Components avec Jest et Testing Library
Testing Library est un ensemble d'outils pour tester les composants React. Il permet une approche plus intuitive et moins liée au DOM interne des composants.
Schéma mental :
- Rendu du composant : Utilise
renderde Testing Library pour rendre le composant. - Interactions : Simule les interactions utilisateur (clicks, saisies, etc.) avec la méthode
fireEvent. - Vérifications : Vérifie l'état et le contenu du composant à travers des sélecteurs.
// Importer Testing Library et le composant à tester
import { render, screen, fireEvent } from '@testing-library/react';
import ButtonComponent from '../path-to-component/ButtonComponent';
// Test React Component with Jest and Testing Library
describe('ButtonComponent', () => {
test('renders button with text "Click me"', () => {
// Rendre le composant
render(<ButtonComponent />);
// Vérifier l'affichage du texte
const button = screen.getByText(/click me/i);
expect(button).toBeInTheDocument();
});
test('calls onClick handler when clicked', async () => {
const mockOnClick = jest.fn();
// Rendre le composant avec un gestionnaire d'événements
render(<ButtonComponent onClick={mockOnClick} />);
// Simuler le clic sur le bouton
fireEvent.click(screen.getByText(/click me/i));
// Vérifier que le handler a été appelé une fois
expect(mockOnClick).toHaveBeenCalledTimes(1);
});
});
Création de Tests pour Pages et API Routes
Next.js permet la création de tests spécifiques pour les pages et les API routes en utilisant Jest.
Schéma mental :
- Définition des tests : Utilise
describeettestpour définir les scénarios de test. - Rendu des pages/API : Utilise
renderRoute(pour les pages) ousupertest(pour les API routes). - Vérifications : Vérifie le contenu retourné par la page/API.
// Importer Jest et supertest pour tester les API routes
import { renderRoute, supertest } from 'test-utils';
describe('API Routes', () => {
test('GET /api/hello returns a greeting message', async () => {
// Effectuer une requête GET à l'API route
const response = await supertest(renderRoute('/api/hello')).get();
// Vérifier le statut de la réponse et le contenu retourné
expect(response.status).toBe(200);
expect(response.text).toBe('Hello World');
});
});
Mise en pratique : projet fil rouge
Pour mettre en pratique ce que nous avons appris, allons-y étape par étape pour créer un mini-projet Next.js avec des tests unitaires.
Étape 1 : Création du Projet
Commencez par créer un nouveau projet Next.js :
npx create-next-app@latest todo-list
cd todo-list
Étape 2 : Création d'une Page et d'un Composant
Créez une page pages/index.js pour afficher la liste des tâches et un composant components/TodoItem.js pour chaque item de la liste.
// pages/index.js
import React, { useState } from 'react';
import TodoItem from '../components/TodoItem';
const Home = () => {
const [todos, setTodos] = useState(['Buy groceries', 'Walk the dog']);
return (
<div>
<h1>Todo List</h1>
<ul>
{todos.map((todo, index) => (
<li key={index}>
<TodoItem todo={todo} />
</li>
))}
</ul>
</div>
);
};
export default Home;
nextjs
// components/TodoItem.js
import React from 'react';
const TodoItem = ({ todo }) => {
return (
<span>{todo}</span>
);
};
export default TodoItem;
Étape 3 : Installation de Jest et Testing Library
Installez Jest et Testing Library comme dépendance de développement :
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
Ajoutez une configuration pour Jest dans next.config.js :
module.exports = {
testPathIgnorePatterns: ['/node_modules/'],
};
Étape 4 : Création des Tests
Créez un fichier de tests pour le composant TodoItem.js.
mkdir __tests__
touch __tests__/TodoItem.test.jsx
Ajoutez les tests unitaires :
// __tests__/TodoItem.test.jsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import TodoItem from '../components/TodoItem';
describe('TodoItem', () => {
test('renders the todo text', () => {
render(<TodoItem todo="Buy groceries" />);
const todoText = screen.getByText(/buy groceries/i);
expect(todoText).toBeInTheDocument();
});
});
Étape 5 : Exécution des Tests
Exécutez les tests avec la commande suivante :
npm test
Vous devriez voir le résultat des tests dans la console.
Erreurs fréquentes et debugging
Erreur 1 : TypeError: Cannot read property 'querySelector' of null
Cette erreur se produit souvent lorsque vous essayez d'accéder à un élément DOM qui n'existe pas encore ou est incorrectement sélectionné.
// ❌ Mauvais
const button = screen.getByText(/click me/i);
fireEvent.click(button); // button peut être null si le texte ne correspond pas
// ✅ Correct
const button = screen.queryByText(/click me/i);
if (button) {
fireEvent.click(button);
}
Erreur 2 : Cannot find module 'some-module'
Cette erreur se produit lorsque Jest ne trouve pas un module importé dans votre test.
// ❌ Mauvais
import SomeModule from 'some-module';
// ✅ Correct
jest.mock('some-module', () => ({
someFunction: jest.fn(),
}));
Erreur 3 : Jest encountered an unexpected token
Cette erreur se produit lorsque Jest ne comprend pas un certain type de syntaxe.
// ❌ Mauvais
const button = screen.getByText(/click me/i);
fireEvent.click(button); // Assurez-vous que vous utilisez la bonne API de Testing Library
// ✅ Correct
const button = screen.getByText(/click me/i);
fireEvent.click(button);
Pour aller plus loin
- Tests d'Intégration: Apprenez à tester l'intégration entre différents composants ou services en utilisant
jest-environment-jsdom. - Mocking avec Jest: Découvrez comment utiliser les mocks pour isoler vos tests et rendre le processus plus rapide.
- Tests End-to-End: Explorerez les tests E2E avec des outils comme Playwright ou Cypress.
Défi pratique: Essayez de créer un test pour une page d'inscription simple dans votre application Next.js, en vérifiant que la saisie des champs et le soumission du formulaire fonctionnent correctement.