Comment écrire des Tests Unitaires sans perdre la tête ?

  1. Comment écrire des Tests Unitaires sans perdre la tête ?
    1. Qu’est-ce qu’un Test Unitaire ?
    2. Pourquoi les Tests Unitaires sont-ils Importants ?
    3. Étapes pour Écrire des Tests Unitaires Efficaces
      1. Choisir le bon Framework de Test
      2. Décomposer le code en simples fonctionnalités
      3. Suivre la méthodologie AAA (Arrange, Act, Assert)
      4. Tester les cas limites et les erreurs
      5. Utiliser des Mocks pour simuler les appels externes
      6. Tester en mode TDD (Test-Driven Development)
      7. Automatiser les Tests
    4. Conclusion

Comment écrire des Tests Unitaires sans perdre la tête ?

Si tu développes des applications depuis un moment, tu as sûrement entendu parler des tests unitaires. Ils sont essentiels pour garantir la qualité et la stabilité de ton code, mais soyons honnêtes, l’écriture de tests unitaires est souvent perçue comme une corvée par de nombreux développeurs.

Pourtant, bien écrire ces tests peut faire la différence entre un projet robuste et une application sujette aux bugs qui te feront perdre des heures (voire des jours) à corriger. Alors, dans ce guide, on va explorer comment écrire des tests unitaires de manière efficace et fluide, tout en restant sain d’esprit !

Qu’est-ce qu’un Test Unitaire ?

Un test unitaire est un test automatisé qui vérifie une petite partie spécifique du code, généralement une fonction ou une méthode. Le but est de s’assurer que cette partie fonctionne comme prévu, indépendamment du reste de l’application.

Contrairement à d’autres types de tests (tests d’intégration, tests de bout en bout), un test unitaire se concentre sur une seule « unité » de code, ce qui le rend plus rapide à exécuter et plus simple à écrire.

Pourquoi les Tests Unitaires sont-ils Importants ?

  1. Détection précoce des bugs : Les tests unitaires permettent de découvrir des bugs plus rapidement, dès la phase de développement.
  2. Refactorisation facilitée : Lorsque tu modifies ton code, les tests unitaires te permettent de vérifier que les nouvelles modifications n’ont pas cassé le comportement existant.
  3. Code plus propre : Si tu écris du code qui peut être testé facilement, tu es obligé de le découper en petites unités logiques, ce qui améliore la lisibilité et la maintenabilité.
  4. Documentation vivante : Un test unitaire bien écrit peut servir de documentation. Il explique comment la fonction est censée se comporter… et oui on y revient, promis je ne parlerai pas plus de documentation dans cet article !

Étapes pour Écrire des Tests Unitaires Efficaces

Choisir le bon Framework de Test

Avant de commencer, il faut choisir le framework de tests. Chaque langage a ses outils, voici quelques frameworks populaires :

  • JavaScript : Jest, Mocha, Jasmine,
  • Python : unittest, pytest,
  • Java : JUnit,
  • PHP : PHPUnit,
  • C# : xUnit, NUnit

Les concepts sont les même pour les différents langages, finalement juste la syntax change.

Décomposer le code en simples fonctionnalités

Pour que ton code soit testable, il doit être découpé en petites fonctionnalités. Une fonction ne doit faire qu’une seule chose, il faut abandonner les fonctions de centaines de lignes et se concentrer sur la fonctionnalité en elle même.

Si il est difficile d’écrire un test unitaire pour une fonction, cela peut indiquer que celle-ci est trop complexe et mérite d’être refactorisée. En plus d’être une bonne pratique, cela facilitera la création des tests unitaires ainsi que la maintenance future.

Dans cet article nous utiliseront Jest de Javascript afin d’illustrer plus facilement les notions. Voici un exemple de fonction simple et claire (alors oui je vous accorde que vous avez rarement à faire avec des codes aussi simples lors d’un projet) :

function add(a, b) {
return a + b;
}

Suivre la méthodologie AAA (Arrange, Act, Assert)

Une bonne pratique pour écrire des tests unitaires est de suivre la méthodologie AAA : Arrange, Act, Assert. Vous la connaissez deja surement sans connaitre le nom en lui même car au final, c’est juste une organisation qui prime sur le bon sens.

  • Arrange : Prépare les conditions de test (instancie les objets, configure les données d’entrée).
  • Act : Exécute le code que l’on veut tester.
  • Assert : Vérifie que le résultat obtenu est celui attendu.

Voici un exemple de ce que cela donnerait avec notre fonction définie précédement. Evident non ? Juste du bon sens.

test('addition de deux nombres', () => {
    // Arrange
    const a = 1;
    const b = 2;
    
    // Act
    const result = add(a, b);
    
    // Assert
    expect(result).toBe(3);
});

Tester les cas limites et les erreurs

Il est facile de tester les cas « idéaux », mais il est encore plus pertinent, voir important de tester les cas où les choses tournent mal. Ce sont ces cas la qui nous intéressent le plus. Il faut s’assurer que ta fonction gère correctement les entrées invalides, les erreurs, ou les situations inattendues.

Rajoutons un cas de test pour notre fonction en incorporant une erreur :

test('addition avec des chaînes de caractères', () => {
    // Arrange
    const a = "1";
    const b = 2;
    
    // Act
    const result = add(a, b);
    
    // Assert
    expect(result).toBeNaN();
});




Utiliser des Mocks pour simuler les appels externes

Lorsque l’on teste une fonction qui dépend d’autres modules ou services externes (API, base de données, etc.), il est crucial de les « simuler » pour isoler la fonction testée. Cela permet de se concentrer sur la logique interne sans dépendre d’éléments externes.

Les mocks sont des objets ou fonctions simulées qui remplacent les vraies dépendances.

Exemple avec Jest pour une fonction qui appelle une API :

const fetchData = jest.fn().mockResolvedValue({ data: 'response' });

test('fonction qui appelle une API', async () => {
    // Act
    const result = await fetchData();

    // Assert
    expect(result.data).toBe('response');
});

Dans cet exemple, la fonction fetchData est simulée avec jest.fn(), et on lui dit de retourner une réponse fictive sans avoir à faire un véritable appel réseau.

Tester en mode TDD (Test-Driven Development)

Pour ceux qui veulent aller plus loin, il existe le TDD (Test-Driven Development). Cette méthodologie consiste à écrire d’abord les tests avant d’écrire le code correspondant. Légérement contraignant au début, cela savère redoutable une fois que l’on s’est habitué.

Exemple de workflow TDD :

  1. Écrire un test qui échoue (car le code n’existe pas encore).
  2. Écrire juste assez de code pour que le test passe.
  3. Refactoriser le code tout en s’assurant que les tests passent toujours.

Un article sera surement écrit si cela vous intéresse, pour parler plus en détail de cette approche.

Automatiser les Tests

Les tests unitaires sont faits pour être automatisés. Il est possible de les lancer a la main mais il est déja éprouvant de les écrire alors si on peut automatiser cette partie autant le faire non? On peut utiliser les processus de CI/CD (Intégration continue / Déploiement continu) via des outils comme Jenkins, GitLab CI par exemple.

Exemple de script pour exécuter des tests avec Jest dans un fichier package.json :

{  "scripts": {
    "test": "jest"
  }
}

Avec cette configuration, une simple commande npm test lancera tous les tests Jest automatiquement.

Conclusion

Les tests unitaires ne sont pas une simple formalité, ils sont une assurance pour la qualité du code. En appliquant ces bonnes pratiques, cela garantira la robustesse de l’application, mais permettront aussi de gagner en sérénité lors de changements ou refactorisations importantes.

Même si ils sont considérés comme inutiles et pénibles par certains développeurs, il faut pratiquer un peu avant de pouvoir se rendre compte que ce n’est finalement pas si terrible ainsi que de leur utilité. Tout comme d’autres bonnes pratiques, cette étape est importante afin de garantir une qualité ainsi qu’une stabilité de l’application.

Et vous, faites vous des tests unitaires dans vos projets professionnels ?


En savoir plus sur Codequeen blog

📩 Reçois les articles CodeQueen directement dans ta boîte mail !

Laisser un commentaire