Jusqu'à récemment j'avais l'habitude d'utiliser la métaphore du filet de pêche pour illustrer la stratégie d'automatisation de tests que l'on applique le plus couramment sur les projets agiles. Cette stratégie est illustrée par la pyramide de Mike Cohn: une forte base de tests unitaires, un étage plus restreint de "spécifications exécutables", et un petit chapeau de tests "bout-en-bout". La métaphore du filet me vient d'un article que j'ai lu il y a quelques années *, qui parlait plutôt d'un filet de sécurité, et que j'ai tenté de m'approprier et remettre à la sauce pêcheur. Ça donne quelque chose comme ça:
"Une stratégie d'automatisation de tests est comme un filet de pêche, plus le filet est grand et ses mailles petites, plus la capacité à attraper des poissons est forte. NB: pour les esprits les moins vifs, les poissons représentent les anomalies. Le filet se doit d'être suffisamment solide pour permettre une utilisation pérenne, et suffisamment bien attaché au bateau pour ne pas perdre sa récolte.
Les tests unitaires représentent les petites mailles de votre filet à attraper des anomalies. Il en faut beaucoup pour couvrir une surface suffisante, et il faut qu'il soit bien unitaire pour que la maille de base soit suffisamment fine, sinon on laisse passer les petits poissons. Ce petit maillage est fait d'un matériel souple qui s'adapte à son environnement: les courants, les bancs de poissons, la résistance de l'eau. Le test unitaire l'est également: les outils et les pratiques (TDD) doivent permettre de le faire évoluer facilement dans son environnement (le code) . Tout comme les petites mailles d'un filet de pêche, un test unitaire peut "casser" sans remettre significativement en question votre capacité à attraper les poissons, il y a beaucoup d'autres mailles dans votre filet. De plus il est facile à réparer pour peu que le pêcheur consciencieux le fasse rapidement.
Ce filet de petites mailles nous paraîtrait presque suffisant. Mais voilà, va-t-il résister aux gros poissons ? Que se passe-t-il si un thon ou un requin blanc se pointe ? Et si l'on accroche le fond ? On risque de perdre tout simplement un gros morceau de son filet, ou d'en jeter une partie parce que "ça ne sert plus à rien". Il faut donc renforcer ce filet avec une structure plus rigide, fait d'un maillage plus large mais dans un matériel plus solide. Cette structure représente les spécifications exécutables. Les tests y sont d'ordre fonctionnel ou métier, ils sont moins fins au regard du code, mais plus solides car ils portent sur des vérifications plus stables dans le temps (le métier). Le code est lui soumis à un remaniement incessant et les vérifications des tests unitaires sont donc moins stables. Le métier, lui, ne change pas tous les jours, le cycle d'évolution est plus long. Néanmoins, le matériel utilisé reste souple pour ne pas subir négativement les contraintes de son environnement. Il faut également trouver le bon dosage de ce maillage afin de ne pas alourdir inutilement notre filet mais de le rendre suffisamment solide. De la même façon les tests des spécifications exécutables doivent représenter les exemples clés, qui facilitent la compréhension des exigences.
Alors, a-t-on maintenant un filet de pêche suffisant ? Non bien sûr. Mais que lui manque-t-il pour être utilisé ? Des fixations pardi! Des câbles, des cordes, des poulies, bref des attaches qui lui permette d'être relié au bateau et d'être manipulé dans son environnement cible, la mer! Ces attaches sont faites d'un matériel lourd et rigide et paraissent solides à première vue, mais elles sont aussi fragiles que les petites mailles car elles centralisent l'ensemble des contraintes de l'environnement. Ces attaches sont les tests de bout-en-bout automatisés. On teste ici l'application déployée dans son environnement (presque) réel. Ces tests ne sont pas nombreux mais indispensables. On teste ici ce qui ne peut pas l'être dans les 2 maillages précédents, comme l'interface graphique ou la performance par exemple."
Finalement je suis revenu à quelque chose de plus simple il y a quelques jours lors d'une soutenance: une métaphore basée sur le principe de la fusée à étage. C'est plus proche de la pyramide et cela s'explique plus rapidement que le filet de pêche. Chaque étage contribue à la mise en orbite du satellite, mais chacun a un rôle bien précis que les autres ne sauraient endosser. Plus on monte dans les étages, plus sa fonction se sophistique et se rapproche de l'objectif final. J'aime également le fait que les étages de la fusée servent directement un objectif métier, la mise en orbite du satellite, alors que le filet de pêche sert plutôt un objectif compensatoire à un système défaillant, la pêche aux anomalies. C'est plus proche de la vision moderne des tests que j'essaye de transmettre.
Et pour vous, l'automatisation des tests est-elle un filet de pêche ou une fusée à étage ?
*Brushing Up On Functional Test Effectiveness, Jennitta Andrea, Better Software Magazine Nov/Dec 2005