Note : 7 ; Une stratégie de tests gravitant hélas uniquement autour des tests unitaires, mais faisant un excellent travail pour en systématiser l’approche.
En matière d’ingénierie logicielle moderne, la littérature sur les tests tend à se concentrer sur les tests unitaires et les tests d’acceptation. Les ouvrages qui englobent les pratiques de manières plus larges ciblent surtout l’aspect méthodologique. C’est donc avec intérêt que j’aborde ce texte qui se focalisent sur les différents types de tests que l’on peut mettre en œuvre au niveau des équipes de réalisation. Et nous allons le voir, cela ne se limite pas aux deux types de tests que nous venons d’évoquer.
Avec 274 pages hors annexes, cela reste un ouvrage de taille raisonnable. Il est structuré en 10 chapitres. Le premier chapitre annonce la couleur : les développeurs qui testent versus ceux qui ne testent pas. L’idée est ici d’avoir un tour d’horizon des types de tests qui vont être abordés et de l’aspect méthode et automatisation qui, même si on ne parle pas d’agilité, restent dans la même idée. Mon désaccord principal, sur ce chapitre et sur le livre, est d’utiliser la pyramide de tests comme boussole, une idée absolument dysfonctionnelle. Bien sûr, l’auteur met l’accent sur les petits tests qui s’exécutent rapidement (donc les tests unitaires), je ne saurais lui reprocher. Mais les autres tests sont pour lui : les tests d’intégration (quels tests d’intégration ?), les tests système et les tests manuels et c’est tout ! Pas de tests fonctionnels ou au moins de tests d’acceptation. C’est une vue erronée du paysage des tests, mais cela ne veut pas dire que l’ouvrage n’a pas d’intérêt.
En fait le chapitre 2 aborde le « specification-based testing ». Mais pas au sens des tests d’acceptation. Il s’agit ici de mettre en place des tests unitaires pour tester les règles de gestion à bas niveau. L’auteur y propose une démarche très systématique en 7 étapes allant des premiers tests passants aux tests aux limites puis « créatifs » sans oublier l’automatisation ! C’est de fait une approche très disciplinée des tests unitaires, peut-être trop, mais cela reste une très bonne source d’inspiration. Le texte ne s’arrête pas là puisqu’il aborde le traitement des bugs. Le propos est largement adossé à de très nombreux exemples en Java. Mais à mon avis l’illustration a travers de règles de validation sur une chaine de caractère n’est pas assez significatif d’un véritable projet.
Le 3ème chapitre aborde un sujet qui fait débat : la couverture de tests ! L’auteur est un partisan de cette approche, mais à ce stade on aura compris que sa stratégie s’appuie très majoritairement sur une approche « boite blanche ». Il n’en reste pas moins que ce chapitre est sans doute ce que j’ai lu de mieux concernant la couverture de tests, car il a une véritable approche sur le sujet qui va bien au-delà de l’approche « ligne de codes » pour laquelle il cache à peine son mépris : le MC/DC qui n’est pas un groupe de hard-rock mais signifie « modified condition / décision coverage ». L’approche est largement illustrée d’exemples non seulement sous forme de code mais à l’aide d’arbre de décision et d’un mini processus pour aider à systématiser l’approche. Difficile de reprocher à l’auteur sa légèreté. La bonne nouvelle est que le mutation testing ne passe pas à la trappe, mais il est traité de manière bien trop légère à mon goût.
On pensait que le design by contract était tombé dans les poubelles de l’histoire, mais non ! L’auteur lui consacre le chapitre 4 et on parle pré-conditions, post-conditions et invariants, à la Eiffel, même si c’est fait en Java ! L’accent est quand même mis sur la validation des inputs, mais le texte n’esquive pas le débat entre validation des entrées et tests. L’impression que laisse ce chapitre est que, contrairement aux deux précédents, l’auteur nous laisse la main pour décider ce que nous allons en faire dans notre stratégie de tests. On n’a pas souvent l’occasion de trouver abordé la question du property-based testing. C’est chose faite ici, en s’appuyant sur l’outillage que nous met à disposition Java, mais c’est l’aspect méthodologique qui retiendra notre attention. Le property-based testing, c’est un peu le test exploratoire façon tests unitaires ! On appréciera la manière très systématique de l’auteur d’aborder cette question et de traiter les questions des valeurs générées aléatoirement et de l’accostage de cette approche avec le contract-based vu au chapitre précédent. Un très bon chapitre.
La question des mocks concernant les tests unitaires arrive assez rapidement. Ce chapitre 6 lui est concerné. Le texte aborde cette question de manière très systématique, d’abord en catégorisant les différentes déclinaisons : stubs, doubles, mocks, etc. Puis en nous faisant découvrir toutes les possibilités offertes par ces outils. Cela, c’est pour l’aspect tactique. Mais le chapitre aborde aussi l’aspect stratégique, car les mocks génèrent bien de la lourdeur de maintenance, voire de la sclérose du design ! L’ouvrage prend donc une position sur la question, concernant ce qu’il faut mocker ou non. Une lecture très utile.
J’avoue que je ne m’attendais pas à trouver dans ce livre ce chapitre 7 consacré aux conséquences de la testabilité sur la conception ! C’est pourtant tout à fait logique étant donné l’angle « boite blanche » adoptée par l’auteur. C’est aussi fort bien traité. Le propos aborde la question à haut niveau en mettant en avant l’architecture hexagonale qui est, je dois dire, très bien expliquée et illustrée ici avec un focus sur le pattern « ports et adapters » qui est en son centre. Son grand frère, l’injection de dépendance trouve naturellement sa place à la suite. Plus inattendu, mais pas illogique, le pattern observer est aussi abordé. Le propos prend un peu de hauteur et, sans nommer explicitement le principe du « system under test », l’auteur nous parle bien de couplage et de cohésion. Un chapitre plutôt complet sur la question.
Que serait un livre qui consacre une si large part aux tests unitaires, s’il n’évoquait pas le TDD. C’est l’objet du chapitre 8. Ce ne sera sans doute pas la référence absolue sur la question, mais le livre fait un travail très propre pour l’aborder. L’idée est sans doute de ne pas chercher à se substituer aux ouvrages totalement consacrés à la question. Le chapitre 9 aborde, quant à lui, les « larger tests ». Si vous pensiez que l’auteur allait lâcher JUnit, alors vous vous mettez le doigt dans l’œil ! On l’outille un peu pour qu’il ne crache pas ses poumons, puis on aborde assez largement le test des bases de données en général et de SQL en particulier et même des pages web. On en fera ce que l’on voudra mais je trouve le propos un peu décousu, même si l’auteur tente de nous proposer un processus, et peu convaincant.
L’ouvrage se referme sur un chapitre 10 consacré à la qualité du code de test. C’est un travail tout à fait honorable pour aborder les propriétés que l’on attend du code et de la conception des tests en particulier pour ne pas devenir un frein à la maintenance. Et c’est une bonne manière de conclure l’ouvrage.
C’est un bon livre. Il aborde de manière structurée et systématique les pratiques de test destinées aux développeurs. L’auteur nous vient du monde académique et il nous donne des éléments d’approche systématisée dont on voit clairement qu’elles sont solidement soutenues par la théorie. Cela donne une dimension plus solide au propos si on le compare aux tests purement empiriques qui sont la majorité. Mais cela peut aussi laisser une impression de lourdeur. A vous lecteur de faire bon usage du matériel mis à votre disposition ! J’ai deux reproches principaux à faire. Tout d’abord, le volet « développement » avec son focus exclusif gravitant autour des tests unitaires ne représente qu’une partie du paysage des tests et l’auteur occulte cela, laissant à penser qu’au contraire cela couvre l’ensemble de la stratégie de test. Le second, qui s’inscrit dans la continuité, est l’utilisation de la pyramide de test comme boussole. Elle n’exprime pas la finalité des tests car elle compare des choses qui ne se comparent pas et focalise la stratégie sur la seule question de la taille des tests, une optique tout simplement erronée ! Le livre reste un très bon livre sur le champ qu’il couvre, avec un propos tout à fait original et intéressant sur la plupart des sujets. Une bonne lecture, donc.
Référence complète : Effective Software Testing – Mauricio Aniche – Manning 2022 – ISBN: 978 1 63343 993 1
