Tests unitaires et intégration continue

Je vais vous parler de deux notions qui sont assez connexes, et que certaines personnes ont tendance à mélanger un peu.

Les tests unitaires

Le but des tests unitaires est d’automatiser les tests de non-régression. Quand on développe un logiciel, on peut facilement faire des modifications sans se rendre compte qu’elles introduisent des bugs dans certains cas particuliers. C’est ce qu’on appelle des bugs de régression, en ce sens qu’on introduit de nouveaux bugs à la suite d’une évolution fonctionnelle. Comme il n’est pas humainement possible de tester systématiquement tous les cas d’utilisation possible, ces bugs peuvent se retrouver déployés en production, avec tous les problèmes que cela comporte.

Une des notions importantes, quand on fait du développement, est de savoir que plus un bug est détecté tôt, plus il sera facile à corriger. Les gros soucis arrivent quand on fait du « sur-développement » par-dessus un bug de régression ; il devient très difficile de faire un retour en arrière sur le code incriminé, car cela impliquerait de supprimer des fonctionnalités. Il faut alors corriger ce nouveau code, en essayant de trouver une aiguille dans une botte de foin.

Concrètement, les tests unitaires consistent en un ensemble de scripts, qui ont chacun en charge la validation d’un morceau de code (ou d’une classe si vous faite de la programmation orientée objet). Il est assez évident de tester de la sorte les bibliothèques de fonction : les « librairies » peuvent être vues comme des boîtes noires, avec des entrées et des sorties. Il suffit d’injecter certaines données en entrée, et vérifier la conformité de ce qu’on obtient en sortie.
Pour du code applicatif, c’est un peu plus délicat, car on est parfois obligé de mettre en place un environnement de test sophistiqué (bases de données avec lots de test, génération de données aléatoires, gestion des tentatives de hack, …). Mais bien heureusement il existe de très nombreux frameworks pour vous aider à y arriver ; suivant votre plate-forme de développement, vous pouvez vous intéresser à JUnit (Java), SimpleTest (PHP), CppUnit (C++), JSUnit (Javascript), ASUnit (ActionScript), Test::Unit (Ruby), Test::Unit (Perl), unittest (Python), NUnit (.NET), …

Le cycle itératif

Si vous avez lu mon billet sur le Cycle en V, vous savez pourquoi ce type de méthode de travail n’est pas adapté à la plupart des projets informatiques, qui réclament une plus grande souplesse. En l’appliquant de manière rigide, on finit par obtenir des logiciels mal adaptés (fonctionnalités sans priorités), livrés en retard (chaque étape bloque les suivantes) et souvent buggués (la technique se plie au fonctionnel).
C’est ainsi qu’est née la méthode du cycle itératif (ou incrémental), qui tente de formaliser une approche plus pragmatique et maniable.

Cycle itératif

Définition

Cette méthode se décompose en 6 étapes, dont 4 qui en constituent le « coeur » :

  • L’expression de besoin : Le client explique ce qu’il veut obtenir. On peut faire un parallèle avec l’étape de faisabilité du cycle en V, et dans une moindre mesure avec les spécifications fonctionnelles. L’idée reste que les informations en entrée peuvent être modifiées par la suite du processus.
  • Le coeur du processus itératif :
    • Spécification : C’est la traduction en langage technique des besoins fournis en entrée. C’est la réponse aux questions « qu’est-ce qu’on fait ? » et « comment on va le faire ? ».
    • Développement : Il s’agit de la réalisation concrète de ce qui a été défini.
    • Validation : C’est l’ensemble des tests qui permettent de s’assurer que le développement effectué correspond bien à ce qui était attendu.
    • Évaluation : Cette étape sert à effectuer un retour sur les écueils rencontrés et les fonctionnalités abandonnées pendant les 3 étapes précédentes, et l’utiliser comme informations d’entrée pour un nouveau cycle.
  • Déploiement : Les livrables qui ont été validés sont déployés pour que le client y ait accès.

Le cycle en V

Le cycle en V est une méthode d’organisation très connue dont l’origine remonte à l’industrie et qui a été adaptée à l’informatique dans les années 80. C’est l’une des premières méthodes qu’on apprend à l’école, et elle reste toujours d’actualité.

La grande force du cycle en V, c’est qu’il définit assez précisément la manière dont les choses devraient se passer.

Cycle en V - théorie

On peut y distinguer 3 grandes parties : La phase de conception, la phase de réalisation (codage) et la phase de validation. Les phases de conception et de validation se découpent en plusieurs parties. Chaque étape ne peut être réalisée qu’une fois que l’étape précédente est terminée, ce qui diminue les prises de risque sur le projet.
Ce qui est bien visible sur le diagramme, c’est que chaque étape de conception possède son alter ego de validation. Il devient alors assez aisé de valider un projet, car le référentiel de test est connu très précisément.

Les différentes étapes

Le cycle en V est constitué de 9 étapes qui ont toutes leur importance.