Vers la livraison facile et continue #2 Le test Agile

Vers la livraison facile et continue #2 Le test Agile

Une histoire de leadership, de bricoleurs et de punks.

Le test est l'un des critères d'un bon code, et on trouve beaucoup de littérature sur le sujet. Pour autant, les mauvaises habitudes persistent alors pourquoi ? Peut-être parce que rarement l'aspect humain est abordé. Avant, la livraison c'était une étape avec des gens autour de l'écran d'un "serveur" sur lequel défilent des lignes de script. Et on croisait les doigts parce qu'après 40 min à les regarder, un échec signifiait tout relancer. L'échec, pouvait provenir d'une erreur de compilation ou d'un test qui ne passe pas.

image.png

Dans ce dernier cas, vers 23h l'équipe se tournait vers le développeur qui avait cassé ce test, et en général c'est lui qui payait les pizzas. En ensuite ledit développeur disparaissait dans de mystérieuses conditions. Un résultat "BUILD SUCCESSFUL" apportait satisfaction et endorphines, la tentation était donc grande d'écrire moins de tests. Moins de tests, moins d'échecs.

image.png

Donc, 3 populations de développeurs ont émergé :

Les leaders

Le fait que le produit soit opérationnel, de qualité et sécurisé est au centre des préoccupations du leader. Il se sent responsable de la fonctionnalité qu'il développe. Ses estimations comprennent la charge de développement et de tests techniques automatisables.

Les bricoleurs

Les bricoleurs ont compris qu'on exigeait d'eux de tester leur code, alors ils développent 1 test "unitaire" bien traversant, qui simule un test humain. C'est moins long à faire, et le build reste SUCCESSFUL. Pourquoi c'est mal ? Il faut y répondre dans un autre article sur la typologie et la pyramide des tests.

image.png

Les punks

De toute façon, l'équipe QA - Quality Assurance - va passer ses cas de test. Et c'est un peu leur job de trouver les anomalies non mais ho. Les punks voient d'abord leur propre sécurité. Il se disent que de toute façon, ils passeront bientôt à un autre projet et que si "ça marche chez moi", alors ça peut bien passer en production. Et si ça plante en production, de toute façon je serai plus là.

Les QA :

Avis subversif : Dans les équipes de punks et bricoleurs, le QA pallie l'absence de tests techniques. Dans une équipe de leaders, le QA n'existe plus parce que l'acceptance technique du projet est assurée à la sortie des développements. Le QA devient Business Analyst, il prend la responsabilité des tests d'acceptance (ceux qu'on ne veut pas / peut pas automatiser), au sommet de la pyramide des tests. Il discute avec le Product Owner en continu, il en est l'ambassadeur auprès de l'équipe de développement. Le BA/QA spécifie le produit, les tests et critères traduisant son acceptance, et exécute ces derniers si nécessaire, comme on le verra un peu + loin.

Ces descriptions se veulent un peu provoc - surtout si vous êtes développeur vous-même - mais sans aucune intention de stigmatiser une population pour plusieurs raisons, car je rappelle qu'on parle d'humain ici.

  • D'abord, l'équipe travaille souvent sous de fortes contraintes projet indépendantes de sa volonté, et qui la poussent à s'adapter : sous-chiffrage, planning irréaliste, microstaffing, aléas matériels, logiciels, humains, dette héritée d'un legacy etc.

  • Ensuite, l'évaluation de la performance d'une équipe est trop souvent réduite à une vision comptable du projet à l'instant t, qui pénalise les investissements. Et le test, c'est un investissement. Sans tests, la dette technique augmente mais sa mesure est rarement incluse dans l'appréciation de la performance d'un projet.

image.png

Si le test unitaire d'un développeur est en échec, la correction du code est immédiate. Le développeur est déjà dans le contexte, se souvient de ce qu'il a fait : la correction est immédiate et quasi à coût 0. Ce coût va croitre avec le temps nécessaire pour détecter l'anomalie: si l'anomalie n'est détectée que lors du build, le développeur doit interrompre ses développements et revenir sur un développement qu'il considérait comme terminé. Si l'anomalie n'est détectée que par les QA, alors on rajoute le temps qu'a passé le QA, les échanges pour qualifier l'anomalie, du temps de rejeu une fois le correctif mis en place. Le pire, si c'est le client qui détecte l'anomalie, peut aboutir à une interruption de la prod, une perte de chiffre d'affaire pour le client, des pénalités pour l'équipe.

Retour en 2009 : les capacités des machines ont bondi, les plateformes de déploiement automatisé sont arrivées, c'est la révolution. Hudson deviendra Jenkins et amènera le concept d'intégration continue qui évoluera avec Gitlab vers les pipelines de déploiement, avec la promesse d'automatiser l'intégration et le déploiement du projet. Menées en continu, ces opérations seront ensuite désignées respectivement par CI, et CD.

Donc l'équipe s'est retrouvée avec une capacité à délivrer en continu, puisque chaque commit sur la branche principale déclenche désormais un build et potentiellement un déploiement, fréquents donc nécessairement rapides. C'est la fin pour les punks, dont les tests traversants durent 30min.

image.png

Donc les erreurs de compilation sont rapportées immédiatement, et peuvent (doivent) être corrigées en priorité absolue. L'équipe livre plus souvent, le QA coûte de + en + cher jusqu'à exploser en plein vol car à peine finit-il son bilan de tests à la charte sous WORD, qu'il lui faut tout recommencer : 2 nouvelles livraisons sont arrivées depuis. Une fois le QA en déni de service, le risque que des anomalies passent au travers des mailles du filet s'accroit. Et comme on manque historiquement de bons tests automatisables, finalement l'équipe livre plus souvent des anomalies au client. Les outils et les règles ont changé du jour au lendemain. Mais pour l'humain, c'est plus progressif.

Cette pénurie de tests fait alors peser une épée de Damotest (la variante) sur l'équipe. Parfois, le projet montre une santé insolente jusqu'à la mise en prod. Et à partir de là, c'est un carnage qui efface bien vite les gains antérieurs (on parle des anos liées aux changements d'heure ?)

La perf d'une équipe de développement doit ainsi se mesurer sur l'ensemble du cycle de vie d'un projet. Renversons donc le paradigme et une fois pour toutes, considérons les tests comme un investissement. Pour cela, arrêtons de faire reposer sur les épaules des chefs de projet un objectif de rentabilité dès la 1ère des 3 années d'un projet. Le retour sur cet investissement s'observera à plusieurs niveaux :

  • sur la rééxécution des tests (non-régression) puisqu'elle est désormais automatisée plutôt qu'humaine donc plus le projet est long, plus ce gain est important.
  • sur la charge de correction d'anomalies de recette et de production.
  • sur le moral des équipes, qui n'ont plus peur du refactoring de code puisqu'un harnais existe pour signifier que quelque chose est cassé.
  • sur le budget des évolutions futures pour la même raison.

Par ailleurs, cette décision déverrouille la possibilité de déployer en continu. Avec un socle de tests automatisés croissant, la confiance de l'équipe augmente à chaque livraison. Le QA disparait petit à petit jusqu'au jour où de livraison continue, on passe à déploiement continu : un build réussi déclenche le déploiement du produit en production. Ouvrant ainsi la voie à de nouvelles stratégies de déploiement, comme le font les grands du web.

Toutefois la marche est haute, et le coût souvent rédhibitoire pour des projets plus petits que Facebook (j'en connais 2 ou 3), d'automatiser 100% des tests. Notamment, je n'ai jamais été convaincu, sauf cas bien précis, de la pertinence d'automatiser des tests d'IHM donc la prédictibilité n'est pas assurée, compte tenu du coût que cela représente.

A chaque projet son contexte, son budget, sa roadmap. Donc à chaque projet son curseur à positionner entre tests automatisables et tests manuels. La 1ère question que l'on doit se poser pour décider : si le QA passe 1h à faire un test manuel et qu'on prévoit au moins 4 livraisons, sommes nous plutôt capables d'automatiser ce test en une demi-journée ?

2e question à se poser : cette fonctionnalité étant critique, est ce que je laisse au QA - humain faillible parmi d'autres - le soin d'en assurer le test ?

Est-ce que quand vous faites construire votre maison vous faites intervenir une équipe qualité à la fin pour vérifier la solidité des fondations ? Ou bien jugez vous que c'est de la responsabilité de ceux qui les ont posées, au moment où ils les posent ? Et si l'équipe qualité détecte une anomalie sur les fondations à la fin, ça coûte combien à corriger ?

Alors le développeur murit, et devient leader. Jusqu'à considérer le test comme la spécification du produit, plutôt qu'un moyen de le vérifier. Mais ça c'est l'objet de l'ATDD (Acceptance Test Driven Development), qui fera sans doute l'objet d'un autre billet.