Tests unitaires, méthodes agiles et intégration continue

De manière générale, l’intégration continue (abréviation CI) permet de garantir une plus grande souplesse et une plus grande qualité dans le processus de développement.

Il est la base des méthodes de développement dites « agiles » et fonctionne avec les tests unitaires.

L’article ci-dessous est une vulgarisation du procédé. Les termes ne sont pas à prendre au pied de la lettre, mais la description est exacte.

La base : les tests unitaires

A l’origine, quand on concevait des logiciels ou des sites web, on faisait des tests soi-même. Ce qui est un bon principe, mais qui a une limite. Cette limite se situe entre la chaise et l’ordinateur : l’humain.

Définition du problème

En effet, 3 problèmes majeurs sont ainsi rencontrés :

  • notre mémoire est limitée, nous sommes faillibles et donc il y a un risque d’oubli des tests à effectuer
  • lorsqu’une équipe reprend un projet, il lui est impossible de connaître parfaitement les tests « évidents » (ou du moins qui le paraissent) réalisés par l’équipe initiale
  • même notés dans un cahier, les tests prennent de plus en plus de temps au fur et à mesure du développement s’ils sont réalisés manuellement.

La solution

La solution, ce sont les tests unitaires.

Présents dans la plupart des langages et dans la plupart des frameworks, ces outils permettent de réaliser des tests de manière automatisée.

Certains langages, comme Java et Ruby, intègrent d’ailleurs nativement cette notion de tests unitaires et sont eux-même développés au travers de ce processus.

Ces tests sont partagés avec le code source. Ce qui permet de les exécuter à tout moment.

Fonctionnement

Le principe est assez simple.

L’idée est de tester chaque élément du code. Par exemple, dans Ruby on Rails, on peut tester :

  • les modèles
  • les contrôleurs
  • les vues
  • les routes
  • les requêtes
  • les emails
  • les fonctionnalités
  • les helpers
  • les tâches automatiques
  • l’affichage du HTML et l’exécution du Javascript
  • etc…

Le champs d’application est très vaste.

En gros, pour ainsi dire tout le code peut être testé.

On rédige les processus de tests et on exécute le tout dans un environnement protégé.

Il existe même des outils qui génèrent un contenu « réaliste » des bases de données (nom, prénom, adresse email, adresse postale, mot de passe, lorem ipsum).

Quand tous les tests passent, l’application est – théoriquement – validée.

On peut alors modifier du code. S’il a un impact par ailleurs, on sera immédiatement au courant.

Le développement piloté par les test (TDD)

Une technique de développement s’est développée autour des tests unitaires : le développement piloté par les tests (test driven development – TDD).

Le principe est de concevoir les tests avant de coder. Ce sont les tests qui influencent le code.

Extreme Programming (XP)

L’extreme programming (XP) est une méthode agile qui implique un travail en binôme.

Dans le binôme, l’un rédige les tests et l’autre le code correspondant. En alternant.

Cela garantit une plus grande qualité du code et également une plus grande efficacité.

Scrum

Dans la méthode de développement SCRUM, le développement est orienté via les scenarii à chaque sprint.

Chaque sprint est divisé en tâches (tickets).

Chaque tâche peut être testée grâce à un ou plusieurs tests unitaires.

Le partage de code source

C’est un élément essentiel pour le travail en équipe. Je vais prendre l’exemple de Git. Pour ma part, j’utilise les services de Github, qui offre un accès (très) sécurisé et performant à une plateforme très complète autour de Git. Sans avoir un coût exorbitant.

Chaque développeur possède une copie du code source et peut la synchroniser à tout moment.

Le suivi du projet

Grâce à une plateforme comme Github, on peut gérer une équipe de développeurs, testeurs et autres. L’évolution du projet se voit en temps réel.

Il existe même un gestionnaire de bugs et demandes de fonctionnalité qui peut être synchronisé avec une interface de gestion de projets agiles (SCRUM). Par exemple Waffle.

Cerise sur le gâteau : chaque envoi de modification (commit) permet d’interagir directement avec les tâches du projet. A chaque tâche est donc associée la portion du code concernée et l’auteur de la modification.

Chaque envoi de modification est réversible, le procédé est donc sécurisé.

L’intégration continue (CI)

Résumons.

Nous avons un code dont la qualité peut être testée grâce aux tests unitaires.

Nous avons également une plateforme de partage de code source, qui nous permet de collaborer en se partageant un même code source en toute sécurité.

Le tout est synchronisé avec notre outil de gestion de projets.

Que nous manque-t-il ? Un processus de déploiement sécurisé.

L’intégration continue permet de déployer une application de manière sécurisée en procédant ainsi, à chaque envoi de modifications (push) ou bien manuellement :

  • récupération du code sur le dépôt de code source
  • préparation d’un environnement d’exécution des tests similaire à l’environnement de production
  • exécution des tests unitaires.

A partir de là, 2 cas de figure :

  • des erreurs ont été rencontrées : le processus s’arrête, un rapport est automatiquement envoyé de sorte à réviser le code et refaire soi-même les tests unitaires, sachant que la portion de code critique a été identifiée
  • tout se passe bien : le déploiement de l’application est réalisé.

Une fois le déploiement réalisé, un test final est effectué afin de valider le fait que le site est toujours fonctionnel :

  • tout fonctionne : c’est parfait, tout est terminé.
  • le site ne fonctionne plus : un rapport est envoyé et l’application est rétrogradée à la version précédente.

L’exemple de Heroku + Codeship

J’utilise Heroku comme plateforme d’hébergement de mes applications web, Codeship (sous forme de composant Heroku) pour le processus d’intégration continue et Github pour l’hébergement du code source.

Déjà, je créé un dépôt privé sur Github pour l’application web. J’y mets mon code source qui intègre déjà les tests unitaires.

Ensuite, je créé mon application Heroku.

4 secondes plus tard, j’ajoute le composant Codeship.

1 seconde plus tard, je configure Codeship. (là, c’est un peu plus long, il y en a bien pour 5 minutes)

En gros, je branche Codeship à mon dépôt de code source Github.

Je définis la configuration de la machine de test.

Je définis le processus de déploiement.

Je fais un envoi de code pour tester, et c’est tout. Mon application est prête pour l’intégration continue.

Sachant que l’intégralité de la solution est proposée en mode « cloud » avec des charges proportionnelles à la taille du projet. Au début, ça coûte une bouchée de pain. Et plus il y a de développeurs et/ou de visiteurs, plus ça coûte cher. Tout en restant raisonnable compte tenu de la qualité des produits.

Pour conclure

Les tests unitaires et l’intégration continue sont les garants de projets de qualité.

Ce sont des outils excellents pour suivre les méthodes agiles. Au-delà d’assurer une qualité irréprochable, ils permettent une souplesse maximale au niveau des équipes.

Si les tests sont bien rédigés, et si en plus on utilise un framework structuré (type Ruby on Rails), un développeur peut être intégré sans risque sur un projet qu’il ne connait pas. C’est un atout majeur.

Evidemment, si vous êtes seul développeur et que vous concevez une application web pour gérer votre collection de pins, ne rentrez pas dans un processus qui deviendrait chronophage.

Le tout est de savoir faire la part des choses et utiliser le bon outil au bon moment.

 

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 )

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 )

Photo Google+

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

Connexion à %s