Présentation
Au cours des dernières semaines, nous avons eu l'opportunité de suivre une formation approfondie sur React et de comprendre son fonctionnement global. Aujourd'hui, pour notre dernier article, nous nous assurerons que tout ce que nous avons appris fonctionne correctement. Pour y parvenir, il est essentiel de tester chaque fonctionnalité de manière indépendante afin de garantir la fiabilité totale de notre projet. À cet effet, nous expliquerons comment réaliser des tests unitaires en React.
Jest
Jest est un framework de tests unitaires, conçu spécifiquement pour React. Il intègre par défaut des dépendances permettant de simuler ('mock') les comportements de React. En effet, Jest offre la possibilité d'accéder au DOM via jsdom, un outil qui reproduit partiellement les fonctionnalités d'un navigateur. Cela permet de tester les composants React dans un environnement qui simule le DOM, éliminant ainsi la nécessité de lancer un navigateur. Jest se distingue par sa rapidité d'exécution et par un ensemble de fonctionnalités avancées, telles que l'isolation des modules et la manipulation des horloges, offrant un contrôle total sur la manière dont le code est exécuté.
React Testing Library
React Testing Library offre des methodes conçues pour tester les composants React sans se baser sur leurs détails d'implémentation. Cette bibliothèque utilise react-dom et react-dom/test-utils pour proposer des fonctions utilitaires favorisant les meilleures pratiques de test.
Plus vos tests reflètent l'utilisation réelle de votre logiciel, plus ils sont susceptibles de vous inspirer confiance.
Ainsi, on faisant des tests on interagit avec des véritables noeuds du DOM.Cette bibliothèque permet de rechercher dans le DOM de la manière la plus proche possible de l'action d'un utilisateur : par exemple, en trouvant des éléments de formulaire via leur texte de label ou des liens et boutons via leur contenu textuel.
En général, l'utilisation de React Testing Library pour effectuer des tests offre une expérience similaire à celle des véritables utilisateurs.
Installation
Jest est par défaut installé dans les projets créés avec create-react-app (CRA). Il n’y a pas de configuration supplémentaire à faire.
La meme chose pour React Testing Library si ce n'est pas le cas voici comment l'installer dans un projet React :
npm install --save-dev @testing-library/react
Pour créer un test avec Jest, il est nécessaire de créer un fichier portant l'extension .test.js. Afin de structurer efficacement un projet React, il est recommandé de placer les fichiers de test dans le même répertoire que les composants, regroupant ainsi tous les fichiers relatifs à ces derniers:

Lancer les tests
Une fois qu'un ou plusieurs tests sont écrits, on peut les exécuter avec la commande suivante pour vérifier s'ils réussissent ou échouent :
npm run test
Voici le résultat si les tests réussissent :

Et voici le resultat s'ils échouent :

Structure du Test :
Contexte :
Voici la fonction formatJobList :
export function formatJobList(title, listLength, index) {
if (index === listLength - 1) {
return title
}
return `${title},`
}
Le but de cette fonction est de formater le titre en ajoutant une virgule à la fin si l'élément courant n'est pas le dernier de la liste.
Voici son utilisation :
<ResultsTitle theme={theme}>
Les compétences dont vous avez besoin :
{resultsData &&
resultsData.map((result, index) => (
<JobTitle
key={`result-title-${index}-${result.title}`}
theme={theme}
>
{formatJobList(result.title, resultsData.length, index)}
</JobTitle>
))}
</ResultsTitle>
test():
Maintenanton passe à écrire ses tests :
Dans notre fichier test nous allons commencer par importer notre fonction :
import { formatJobList } from './'
Chaque test va permettre de vérifier un élement spécifique de la fonction, voici un premier test :
import { formatJobList } from './'
test('ajoute une virgule à un item', () => {
const expectedState = 'item2,'
expect(formatJobList('item2', 3, 1)).toEqual(expectedState)
})
Ce test vérifie le fonctionnement de la fonction formatJobList en s'assurant qu'elle ajoute bien une virgule à la fin d'un élément qui n'est pas le dernier de la liste.
Remarque:
test() prend une chaîne de caractères comme premier argument pour identifier le test et une fonction comme deuxième argument pour l'exécuter.
describe():
Cette méthode permet de regrouper plusieurs tests qui partagent un contexte commun, rendant leurs résultats plus lisibles lors de l'exécution. Plutôt que d'utiliser test() pour chaque test, on peut utiliser l'alias it(), qui fonctionne de la même manière :
import { formatJobList } from './'
describe('La fonction formatJobList', () => {
test('ajoute une virgule à un item', () => {
const expectedState = 'item2,'
expect(formatJobList('item2', 3, 1)).toEqual(expectedState)
})
test('ne met pas de virgule pour le dernier élément', () => {
const expectedState = 'item3'
expect(formatJobList('item3', 3, 2)).toEqual(expectedState)
})
})
A l'execution ca donne ceci :

Simuler des modules:
Certains modules peuvent être difficiles à tester ou leur test peut s'avérer inutile, car ils ne sont pas essentiels à la fonctionnalité que nous cherchons à vérifier. Dans ces cas, il est possible de simuler (ou "mock") ces modules pour simplifier l'écriture de nos tests. Cette approche permet de se concentrer sur les aspects critiques de l'application sans être entravé par des dépendances complexes ou non pertinentes.
Prenons par exemple le composant Contact
qui intègre un composant tiers GoogleMap
:
import React from "react";
import { LoadScript, GoogleMap } from "react-google-maps";
export default function Map(props) {
return (
<LoadScript id="script-loader" googleMapsApiKey="VOTRE_CLÉ_API">
<GoogleMap id="example-map" center={props.center} />
</LoadScript>
);
}
// contact.js
import React from "react";
import Map from "./map";
export default function Contact(props) {
return (
<div>
<address>
Contacter {props.name} par{" "}
<a data-testid="email" href={"mailto:" + props.email}>
e-mail
</a>
ou sur son <a data-testid="site" href={props.site}>
site web
</a>.
</address>
<Map center={props.center} />
</div>
);
}
Pour tester le composant Contact, il n'est pas nécessaire de tester le composant de la carte (map) ; pour cela, nous allons simplement le simuler en utilisant jest.mock(), afin qu'il retourne un composant factice :
jest.mock("./map", () => {
return function DummyMap(props) {
return (
<div data-testid="map">
{props.center.lat}:{props.center.long}
</div>
);
};
});
Mise en place et nettoyage :
Dans les tests de composants React, il est essentiel de rendre le composant dans un élément DOM et de le nettoyer après chaque test pour éviter les interférences entre les tests. Utiliser beforeEach pour préparer l'environnement de test et afterEach pour le nettoyer garantit que chaque test démarre avec un état propre:
import { unmountComponentAtNode } from "react-dom";
let container = null;
beforeEach(() => {
// met en place un élément DOM comme cible de rendu
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// nettoie en sortie de test
unmountComponentAtNode(container);
container.remove();
container = null;
});
act():
Dans les tests d'interfaces utilisateur, on réalise différentes actions comme afficher des éléments, cliquer sur des boutons ou charger des données. Ces actions sont essentielles. Pour nous aider, il existe une fonction pratique nommée act() dans react-dom/test-utils. Elle garantit que toutes ces actions sont correctement réalisées et reflétées sur la page avant que nous ne commencions à vérifier si les résultats attendus sont obtenus.
En général, on peut dire que cette méthode permet de reproduire l'expérience vécue par de véritables utilisateurs.
Voici un exemple de composant :
import React from "react";
export default function Hello(props) {
if (props.name) {
return <h1>Bonjour, {props.name} !</h1>;
} else {
return <span>Salut, étranger</span>;
}
}
Et voici son test :
it("s’affiche avec ou sans nom", () => {
act(() => {
render(<Hello />, container);
});
expect(container.textContent).toBe("Salut, étranger");
act(() => {
render(<Hello name="Jenny" />, container);
});
expect(container.textContent).toBe("Bonjour, Jenny !");
act(() => {
render(<Hello name="Margaret" />, container);
});
expect(container.textContent).toBe("Bonjour, Margaret !");
});
L'objectif de ce test est de vérifier le comportement du composant Hello en fonction des props qui lui sont passées.
Bonus de la semaine :
Une fois qu'on a des tests en place, on peut commencer a calculer la couverture de tests. En effet, de savoir le pourcentage precis du code qui est verifié par les tests. Ce qui permettra une plus grande efficacité, productivité des tests et assurer le controle du code.
Pour cela , il suffit d'executer cette commande : npm test -- --coverage
ce qui donne :

Conclusion
Au terme de notre exploration de React et de son écosystème, nous sommes passés par la compréhension des fondamentaux de React, des concepts avancés, de la connexion avec une API jusqu'à l'apprentissage de pratiques efficaces pour les tests. Cette aventure nous a permis non seulement d'apprendre à créer des applications frontend avec React, mais aussi à assurer leur maintenance et leur fiabilité.
Puis, à tous ceux qui utiliseront React, je vous souhaite un bon développement !
Réferences
Aperçu des tests.React. https://fr.legacy.reactjs.org/docs/testing.html (consulté le 20 mars 2024)
Recettes de test.React. https://fr.legacy.reactjs.org/docs/testing-recipes.html (consulté le 20 mars 2024)
MCCURDY NICK.(2023, 29 octobre).React Testing Library Example.Testing Library. https://testing-library.com/docs/react-testing-library/example-intro (consulté le 21 mars 2024)
AUGEY LOU.(2023, 26 janvier). Faire des tests unitaires dans les applications React avec Jest et Testing-Library. Medium. https://medium.com/@lou.augey/faire-des-tests-unitaires-dans-les-applications-react-avec-jest-et-testing-library-cf6009401872 (consulté le 21 mars 2024)
HOFF NORDWIN.(2017, 9 février). React et les tests unitaires. Developpez.com. https://soat.developpez.com/tutoriels/javascript/test-unitaires-applications-react/ (consulté le 20 mars 2024)
ANTONIO AURÉLIEN ET ALEXIA TOULMET ET TECHER JEAN SÉBASTIEN.Découvrez la base des tests dans React avec Jest.OpenClassrooms. https://openclassrooms.com/fr/courses/7150606-creez-une-application-react-complete/7256627-decouvrez-la-base-des-tests-dans-react-avec-jest (consulté le 21 mars 2024)
Commentaires1
Très intéressant
L'utilisation de Jest et React Testing Library est très bien expliquée, avec des exemples concrets et des instructions claires sur la manière de les installer et de les utiliser dans un projet React. savez-vous quelles sont les principales différences entre Jest et React Testing Library, et quand est-il préférable d'utiliser l'un ou l'autre ? merci