Intégration continue : vers le « continuous testing »

L’intégration continue est une des treize pratiques de « l’extreme programming ». Elle vise à intégrer immédiatement les modifications du produit afin d’éviter la surcharge de travail liée à l’intégration de tous les éléments avant la livraison. Les tests facilitent grandement cette intégration : quand tous les tests passent, l’intégration est terminée.

Les outils d’intégration continue sont en fait assez simples (que ce soient Jenkins, Bamboo, ou TeamCity pour ne citer qu’eux). Il s’agit principalement d’un « ordonnanceur » qui se réveille lorsqu’un développeur « commit » du nouveau code dans le référentiel de contrôle de version (git, svn, …). Cet ordonnanceur lance des tâches visant à vérifier la qualité du nouveau « build ».

Il est très important de bien définir les tâches que doit réaliser la plateforme d’intégration continue, c’est de là que provient la qualité de votre intégration continue. En effet, votre « pipeline » d’intégration pourrait se contenter de juste compiler votre code. Mais dans ce cas il ne s’agit plus d’intégration continue, et votre « build » serait alors « vert » sans aucune information sur la qualité.

Les tâches de l’intégration continue devraient à minima contenir :

  • La compilation et le « packaging » de l’application
  • L’exécution des tests unitaires et la vérification de leur couverture
  • Une analyse statique de la qualité du code (ou « test statique »)

Ceci n’est qu’un minimum, et ne permettra que de vérifier l’intégration logicielle, si vous voulez faire un pas vers le « continuous delivery », il faudra ajouter des tests fonctionnels et non fonctionnels automatiques. Un « pipeline » d’intégration continue devrait alors ressembler à cela :

1

Si la première partie est souvent (partiellement) présente, c’est rarement le cas pour les tests de plus haut niveau. Ils posent en effet des problèmes beaucoup plus complexes que de « simples » tests unitaires. Pour rappel, les tests unitaires (pour être de vrais tests unitaires) n’utilisent aucun environnement, embarquent leurs jeux de données, et de ce fait sont indépendants, peuvent être joués en parallèles et sont rapides à exécuter. Ce n’est généralement pas le cas des tests de plus haut niveau.

Les tests de plus haut niveau posent différents problèmes pour être automatisés et lancés en intégration continue :

  1. Ils demandent un environnement et des données qui ne sont pas toujours disponibles
  2. Ils sont souvent moins stables que les tests de bas niveaux, comme ils traversent toutes les couches de l’application, ils ont beaucoup plus de raisons d’échouer et de faire de faux positifs
  3. Ils sont plus lents à exécuter

En fait ces tests demandent une maturité en tests importante, et d’utiliser des pratiques et des outils adéquats avant d’être mis en place dans l’intégration continue :

  1. Virtualiser les environnements et les données et les créer à la demande. Des outils, comme Docker ou VMWare, permettent d’isoler les environnements virtuels, et les outils de virtualisation de services, comme WireMock par exemple, permettent de simuler les interfaces externes, et donc de bouchonner vos tests
  2. Eviter de lier trop fortement vos tests à votre interface utilisateur, c’est en effet la partie la moins stable, il faut donc soit baser les tests sur la couche API, soit utiliser des frameworks de tests qui ont une couche d’abstraction forte entre le test et l’IHM (comme Serenity BDD par exemple)
  3. Faire en sorte que tous les tests automatisés soient maintenus en même temps que le code permet d’assurer que ces tests sont vraiment maintenus. C’est en effet une bonne pratique de l’intégration continue : « qui casse le build, le répare ». C’est donc au développeur de mettre à jour tous les tests (et pas uniquement les tests unitaires) impactés par sa modification
  4. Faire de vos tests votre documentation vivante en la publiant et la mettant à disposition du métier à la fin du processus de build (sur un wiki par exemple)
  5. Mettre en place un autre principe de l’extreme programming : le build en moins de 10 minutes. Ceci signifie que les tests, même de bout en bout, doivent être « timeboxés ». Si leur exécution dépasse le délai imparti, il faut supprimer des tests !

Comme on le voit, l’intégration continue n’est pas juste une question de plateforme d’intégration continue, mais bien de process de build incluant des tests matures et maîtrisés.

Installer Jenkins (certainement la plateforme la plus populaire) n’est donc pas suffisant, il faut surtout revoir comment sont gérés les tests automatiques, et respecter les pratiques agiles comme la pyramide de tests.

La réussite dans un projet agile est avant tout une question de tests. L’intégration continue vous permettra de lancer régulièrement et sans même y penser ces tests, et d’assurer cette intégration, mais cela nécessite une bonne maitrise et l’utilisation d’outils adéquats.

Publié par

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s