TestMethodOrder : un coup de pouce à utiliser avec précaution

JUnit et son ordre fantasque

Dans certains contextes techniques, nous pouvons choisir simplement l’ordre d’exécution des tests automatisés. Par exemple, Test Batch Runner permet de lancer une suite de tests UFT selon l’ordre indiqué dans le fichier mtb (modular test batch) associé.

En revanche, quand on utilise JUnit, par défaut, ce n’est pas le cas. Le nom des méthodes de test sont hashées, puis les tests sont lancés par ordre alphabétique de hash. Nous nous retrouvons donc à chaque fois avec le même ordre d’exécution, mais à première vue celui-ci ne rime à rien. Ça peut même être assez agaçant au début quand on découvre l’outil !

Un test d’indépendance

Si vos tests autos respectent une des bonnes pratiques capitales en la matière, à savoir qu’ils sont tous indépendants les uns des autres, cela ne devrait cependant pas vous poser problème. En principe, ils devraient pouvoir être joués dans n’importe quel ordre.

Le fait que JUnit lance les tests dans cet ordre particulier peut donc être apprécié, et utilisé comme une manière de vérifier que les tests sont bien indépendants les uns des autres. Du coup, pourquoi ne pas aller encore plus loin ?

Soyons encore plus fous

Pour aller au bout de la logique, nous pourrions décider de jouer les tests dans n’importe quel ordre, cet ordre pouvant changer à chaque exécution. Pour cela, nous allons nous baser non plus sur le hash des noms de méthodes, mais sur l’ordre d’exécution de la JVM, qui n’est pas fixe. Pour ce faire, ajouter simplement « @FixMethodOrder(MethodSorters.JVM) » juste au-dessus de votre classe de test. Cette solution est compatible avec JUnit 4.

@FixMethodOrder(MethodSorters.JVM)
public class TestExemple {

    @Test
    public void test001(){
        System.out.println("1");
    }

    @Test
    public void test002(){
        System.out.println("2");
    }

    @Test
    public void test003(){
        System.out.println("3");
    }

}

Vos tests se joueront maintenant dans n’importe quel ordre, ce qui vous permettra de prouver qu’ils sont vraiment indépendants.

Un ordre fixe

Maintenant, il peut arriver que vous ayez besoin de lancer les tests dans un certain ordre. Si tel est le cas, il suffit simplement de remplacer « MethodSorters.JVM » par « MethodSorters. NAME_ASCENDING », et de ranger les tests par ordre alphabétique en fonction de l’ordre voulu. Cette solution est compatible avec JUnit 4.

D’autres méthodes sont arrivées avec JUnit 5. Par exemple, ceci affichera 1, 2, puis 3, en se basant sur les annotations @Order :

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)

public class TestExemple {

    @Test
    @Order(2)
    public void ccc(){
        System.out.println("2");
    }

    @Test
    @Order(1)
    public void bbb(){
        System.out.println("1");
    }

    @Test
    @Order(3)
    public void aaa(){
        System.out.println("3");
    }
}

Pour conserver un ordre alphabétique et ne pas s’encombrer d’annotations, la syntaxe suivante peut être suivie :

@TestMethodOrder(MethodOrderer.Alphanumeric.class)

public class TestTmp {

    @Test
    public void bbb(){
        System.out.println("2");
    }

    @Test
    public void ccc(){
        System.out.println("3");
    }

    @Test
    public void aaa(){
        System.out.println("1");
    }

}

Celle-ci affichera 1, 2, puis 3.

Quelle que soit la notation choisie, si vous optez pour cette logique, pesez bien le pour et le contre avant de vous lancer.

Exemple de mauvaise utilisation

Une rangée de dominos peut tenir debout pendant des années. Mais il suffit que l’inscription de Boniface07 se déroule avec un petit accroc pour que tous les tests de cette classe se retrouvent en échec.

FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestExemple extends MaSuperAppliWebTest {

    @Test
    public void test001_inscriptionUtilisateur(){
        accesURL("https://masuperappliweb.com/inscription");
        inscription("Boniface07", "password");
        verifierMessageConfirmationInscription();
    }

    @Test
    public void test002_premiereConnexionUtilisateur(){
        accesURL("https://masuperappliweb.com/connexion");
        connexion("Boniface07", "password");
        verifierPageAccueilAffichee();
    }

    @Test
    public void test003_configurationCompte(){
        accesURL("https://masuperappliweb.com/connexion");
        connexion("Boniface07", "password");
        configurerCompte();
        verifierCompteBienConfigure();
    }

}

Un exemple de motif recevable

Le test X a besoin d’un jeu de données. Celui-ci peut être rapidement créé via une IHM, mais un traitement en back-office durant environ 15 minutes doit être effectué. Nous n’avons pas envie de gaspiller 15 précieuses minutes à attendre la fin de ce traitement ! Nous lançons donc cette création de données au début, nous jouons une flopée de tests ensuite, et seulement à la fin, le test devant utiliser le jeu de données. Des commentaires clairs font état de cette dépendance exceptionnelle. On pourrait même dire qu’on est en présence d’un seul scénario coupé en deux méthodes de test.

Ce n’est pas le seul motif recevable, mais cet exemple montre que cela doit rester exceptionnel et justifié.

A bientôt et bonne automatisation des tests !

Les 7 principes généraux du test logiciel illustrés par la pandémie

A l’heure où cet article est publié, une partie importante de la population mondiale vit confinée. Le coronavirus est de toutes les conversations, il modèle notre quotidien et habite nos pensées à tout moment. Difficile de relire les 7 principes généraux du test logiciel sans que le parallèle avec la situation actuelle ne saute aux yeux…

Cet article est aussi l’occasion pour toute l’équipe Hightest de vous souhaiter bon courage en cette étrange période, où que vous soyez.

Les tests montrent la présence de défauts

Sur un million de dépistages, 1 dépistage positif suffit à signifier que le virus est encore là. Cependant, si tous les dépistages sont négatifs, cela ne signifie pas que le coronavirus a disparu de la population globale.

Les tests exhaustifs sont impossibles

On ne peut pas dépister simultanément 7 milliards d’êtres humains et analyser toutes les surfaces potentiellement infectées du monde entier. Par ailleurs, d’autres tests seraient envisageables : vérifier la présence du virus dans l’air, vérifier tous les animaux pouvant en être la source, tester la transmission sur les pingouins…

Tester tôt

Dépistage rapide ➔ prise en charge rapide ➔ contagion mieux maîtrisée. Ce principe a été mis en application avec succès à Singapour. Les Etats-Unis au contraire ont montré le contre-exemple.

Regroupement des défauts

Certaines zones géographiques sont beaucoup plus touchées que d’autres, comme l’indique cette carte.

Paradoxe du pesticide

Sur une population d’un million de personnes, si on dépiste à chaque fois les 100 000 mêmes personnes, on risque fort de passer à côté de malades.

Les tests dépendent du contexte

A l’heure actuelle, il ne serait pas pertinent de faire dépister les astronautes de retour de l’ISS.

L’illusion de l’absence d’erreur

Jeudi 19 mars en Nouvelle-Calédonie, nous étions rassurés : nous pensions qu’il n’y avait aucun cas parce aucun n’avait encore été détecté ; en réalité, il y en avait déjà 2.

Nous souhaitons encore bon courage à toutes les personnes qui nous lisent ainsi qu’à leur entourage personnel et à leurs collègues. Prudence avant tout.

Crédit image : benjamint444

[Invité] Comment Ouest-France a intégré le BDD dans son legacy ?

Dans l’article précédent, nous proposions quelques ressources pour (mieux) appréhender le Behavior Driven Development. Mais quid de l’implémentation de cette méthodologie dans le cadre de projets dont le code historique (ou legacy) représente une part très importante ? Florent Vaution, Software QA Manager chez Ouest-France, a tenté l’expérience et présente ici son témoignage.

Origines de la démarche

Quel contexte de départ ?

A mon arrivée chez Ouest-France il y près de 3 ans, un parcours d’intégration est organisé et me permet de rencontrer différents acteurs qui gravitent autour du SI : métiers du commerce/marketing, métiers du numérique, journalistes, membres de la DSI. A cette occasion, je fais rapidement deux constats :

  • Le premier est qu’il y avait un manque de confiance des équipes métiers vis à vis de la production de la DSI. C’est pourquoi les équipes métiers vérifiaient systématiquement tous les cas d’usages, nominaux ou non, sur les produits livrés. Et, bien souvent, dès qu’un problème survient, les équipes de la DSI étaient pointées du doigt.
  • Le second est que les membres de la DSI se désengagent petit à petit de la qualité de leur production. Ils souffrent de cette défiance et du manque de sens par rapport à ce qu’on leur demande de produire.

Beaucoup plus proche de mon métier, je note aussi un manque cruel de formalisation des tests ainsi qu’une documentation pas forcément à jour, ou quand elle l’est, l’effort important de mise à jour en cas d’évolution.

Qui a eu cette idée folle ?

L’idée de rapprocher ces acteurs via une approche BDD émerge assez rapidement. Avec pour objectifs de casser cette défiance, de faire comprendre aux métiers les contraintes et problématiques de la DSI, de redonner du sens aux équipes techniques vis à vis de ce qu’elles produisent pour qu’elles s’investissent et s’approprient leur production. Et ceci pour tous les services de la DSI, des sites web à la distribution du journal dans les boîtes aux lettres des abonnés, de la gestion du compte client à l’impression quotidienne du journal papier.

Un challenge quotidien !

Dans les coulisses de Ouest-France

OK, pour le BDD on comprend bien. Mais il est où le legacy là-dedans ?

Faisons un focus sur cette performance quotidienne qui est d’imprimer tous les jours à près de 600 000 exemplaires du journal papier divisés en 52 éditions (une édition correspond à une zone géographique précise, la zone de Rennes représente 5 éditions par exemple : centre, est, nord, ouest, sud, et chaque édition comporte des pages locales différentes) et répartis sur 3 imprimeries différentes. Ce miracle est possible principalement grâce à un gros legacy. La majorité des applications sont âgées de 15 – 20 ans, et il y a, heureusement, très très très peu de turn-over. Ce qui signifie qu’une partie des personnes qui ont créé ces applications sont toujours présentes et donc qu’elles sont très bien maîtrisées et peu soumises aux défauts.

Les rotatives de Ouest-France, à Rennes le 24 novembre 2014 afp.com/DAMIEN MEYER

L’équipe technique de la DSI est en charge de maintenir et faire évoluer les solutions de mise en page et d’impression du journal papier.

Au niveau organisation, l’équipe technique de la DSI est constituée de PPO, de 5 développeurs, d’un scrum master et d’un testeur. Une petite équipe pour gérer un petite trentaine d’applications différentes. Le legacy est géré grâce à la méthodologie Kanban. Les applications plus récentes et encore en cours de développement sont gérées par la méthodologie Scrum.

Mon rôle dans cette organisation est d’aider à établir la stratégie de test sur les différentes applications développées, de partager les bonnes pratiques venant d’autres équipes et d’accompagner les membres de l’équipe dans ce changement pour qu’il se passe de la meilleure façon possible. A noter que la démarche est aussi déployée dans plusieurs autres équipes.

Côté documentation des différents applicatifs, elle est maintenue sous Word depuis leur création. Côté tests, uniquement des campagnes de non régression étaient présentes dans Testlink mais sans réelle traçabilité avec les “exigences”.

Un journal, trois domaines fonctionnels

Les solutions développées sont utilisées au sein de trois domaines fonctionnels :

  • celui des journalistes, qui créent la maquette éditoriale du journal qui partira à l’impression le soir même
  • celui des coordinateurs, qui s’assurent que les 52 éditions différentes sont complètes avec leurs publicités respectives, leurs avis d’obsèques, leurs annonces légales…
  • celui de l’impression en elle-même. On entre dans le domaine industriel (rotatives)

La qualité : un enjeu crucial

Mais pas facile de faire évoluer un processus industriel qui doit fonctionner tous les jours et qui est soumis aux aléas de l’actualité ! En effet, une information de très grande importance et qui arrive tardivement après le bouclage, peut nécessiter une reprise de la maquette complète du journal (modification, ajouts ou suppression de pages). Les applications mises à disposition doivent donc être prêtes à aborder ces dernières nouvelles.

Le moindre défaut sur cette chaîne peut prendre des proportions considérables : maquette éditoriale à revoir donc décalage de l’impression et distribution plus tendue, remplacement de publicités donc perte de CA et de confiance des annonceurs déjà peu nombreux, non impression de tout ou partie des éditions donc perte de CA. A titre d’exemple, ne rien imprimer représente une perte quotidienne de 600K€ environ.

Passer au BDD : notre plan d’action

C’est dans ce contexte très établi que je mets les pieds dans le plat. Heureusement, mon discours a un écho favorable auprès de plusieurs personnes, notamment auprès du DSI,  et nous mettons en place un plan d’action en 3 étapes.

© investissements.org

Première étape : expliquer la démarche

Pourquoi changer ? Cette question, je l’ai entendue souvent. Et il m’arrive encore de l’entendre. La réponse n’est pas évidente quand on est sur un système qui fonctionne, qui permet de produire correctement le journal tous les jours. Néanmoins, nous arrivons aux limites d’un système. Les applications sont basées sur des technologies anciennes, une partie des personnes qui y ont contribué est passée à autre chose (mobilité interne, retraite). Se pose donc la question de la mise à jour et de l’évolution de ces applications.

C’est une réelle opportunité pour démarrer la démarche BDD !

J’ai donc commencé par mettre au point une formation pour expliquer ce qu’est le BDD et ce que j’en attends : de la collaboration entre équipes métiers et équipes techniques !

La formation mêle les concepts théoriques et des ateliers pratiques de réflexion collective pour répondre à un besoin. Le besoin est fictif et volontairement hors de leur champ de compétences mais on peut aussi prendre des cas très concrets.

Bien sûr, l’aspect formalisation qui accompagne cette démarche est abordé et quelques règles sont données pour bien commencer.

L’écho de cette formation a été plutôt bon, et quelques jours plus tard l’équipe a décidé de se lancer dans la démarche. Les membres de l’équipe ont donc bien saisi l’opportunité qui s’offraient à eux.

Nous avons alors défini un plan d’accompagnement pour supporter la démarche et rendre l’expérience la plus bénéfique possible.

Deuxième étape : profiter d’un contexte d’évolution sur un produit exemple

Un POC interne

Nous avons défini ensemble le contexte le plus favorable pour se lancer. Et nous avons profité de l’évolution mineure d’une application existante. L’idée était double :

  • traiter l’évolution avec cette nouvelle méthode
  • valider la démarche avec l’équipe sur un cas concret de leur périmètre

Nous avons fait le choix de mettre le testeur de l’équipe au centre de la mise en place de cette démarche. Nous avons estimé qu’il était le mieux placé pour à la fois formaliser les discussions autour de l’évolution et exprimer des contraintes de test.

Faux départ et rollback

Le plan ne s’est malheureusement pas déroulé sans accroc. L’écueil que nous avons rencontré est que ce testeur n’avait finalement pas totalement saisi les objectifs et qu’il a aussi repris la totalité des fonctionnalités de l’application mais d’une mauvaise façon. Le testeur a utilisé une méthode très directive avec une action par step. Ce qui inclut des steps techniques non compréhensibles par l’ensemble des membres de l’équipe. On est alors en contradiction avec les principes premiers de la démarche BDD.

Ce qui fait que nous nous sommes donc retrouvés avec un patrimoine de plusieurs centaines de scénarios inutilisables. Grosse frustration du testeur et de moi-même, et léger moment de doute. Mais on se remotive collectivement car on se dit que c’est tout de même la bonne démarche !

© reussitepersonnelle.com

Donc on efface tout et on recommence. J’ai fait des ateliers plus précis avec lui et le Scrum Master pour s’assurer que nous étions tous sur la même longueur d’ondes. Ces ateliers étaient basés sur des cas très concrets et mettaient en avant l’aspect collaboratif. Pourquoi ces 2 personnes uniquement ? Parce que le testeur se faisait le représentant de l’équipe technique et le Scrum Master le représentant de l’équipe métier. Je dis bien le Scrum Master car :

  • c’est lui qui a le plus de connaissances métier dans l’équipe et donc qui peut rapidement dire si un scénario est compréhensible ou non
  • c’est lui qu’il faut surtout convaincre
  • il n’y a pas de PO mais plusieurs PPO qui ont été épargnés lors de cette première phase pour qu’ils continuent à avancer sur les sujets opérationnels

Et aussi tout simplement parce que ces deux personnes sont les plus à même à faire passer des messages au quotidien à l’ensemble de l’équipe.

Donc nous sommes repartis pour un tour. Au-delà de l’aspect perte de temps engendrée par cet écueil, cela a permis de montrer que cette démarche BDD n’est pas si évidente que cela à formaliser afin que tout le monde ait le niveau d’information suffisant et la même compréhension d’une fonctionnalité.

Quand la BDD-mayonnaise prend…

Une autre question s’est aussi levée au début de la démarche : doit-on aussi mettre à jour la documentation existante (Word) ? Nous avons collectivement fait le choix de ne pas le faire. Cela démontre l’adhésion à la démarche initiée et la volonté de la faire aboutir.

Une fois le bon niveau de formalisation atteint, il a fallu reprendre l’existant depuis la documentation existante afin d’obtenir une documentation centralisée et facilement évolutive.

La suite a été la prise en main de la démarche par l’ensemble de l’équipe. Nous avons poursuivi la démarche en ajustant les pratiques avec l’ensemble des membres de l’équipe pour atteindre la bonne façon de faire. Quand je dis la bonne façon de faire, cela signifie que c’est la façon qui convient à tous les membres de l’équipe.

Et ça fonctionne bien ! Les membres de de l’équipe ont bien sûr eu une période de prise en main nécessaire. D’où l’intérêt d’avoir deux personnes à leurs côtés pour échanger, corriger, améliorer leurs pratiques, de manière collaborative. Néanmoins, l’équipe s’est révélée opérationnelle dans l’application de la démarche BDD.

Troisième étape : déployer la démarche sur les autres produits

Mise à profit du retour d’expérience

Une fois cette étape franchie sur une application, il faut réfléchir au déploiement de la démarche sur les quelque trente autres.

Nous avons appliqué la même tactique qu’avec la première : toujours profiter des  opportunités engendrées par les évolutions, les refontes de produit, les nouveaux développements. C’est donc au gré des événements que le déploiement s’est déroulé et continue à se dérouler car toutes les applications n’ont pas subi d’évolutions et donc ne sont pas inscrites dans la démarche BDD. A ce jour, 16 applications voient leur développement guidé par cette démarche collaborative. Les autres suivront tôt ou tard. Les équipes sont prêtes.

Nouvelle péripétie !

Mais comme rien n’est parfait dans ce bas monde, nous avons dû faire face à un imprévu en cours de route : le départ du testeur qui avait entamé la démarche et qui en était le référent dans l’équipe. Nous avons donc entamé des recherches pour le remplacer et pour poursuivre l’effort au sein de l’équipe. C’était un coup dur car la dynamique était bonne et cet évènement risquait de balayer tous les efforts accomplis.

De plus, trouver la bonne personne pour animer la démarche au quotidien n’a pas été une chose facile.Il faut mêler de bonnes compétences en test (c’est quand même le métier premier) et des soft skills pour embarquer rapidement dans la démarche et l’animer au quotidien. Une combinaison pas si courante que ça autour de nous.

En effet, ce n’est pas parce que les autres membres de l’équipe sont autonomes qu’il n’y a plus rien à faire. C’est peut-être même à ce moment que l’effort doit être plus important pour toujours chercher de l’amélioration, ne pas s’endormir sur des certitudes. Et donc, il faut un animateur de la démarche, un référent, qui peut pousser les autres membres de l’équipe à s’améliorer, à penser à tous les impacts d’une évolution, qui peut s’assurer que tout se déroule correctement, qu’il n’y a pas de raccourci de fait, qui peut répondre à des questions sur la méthode, l’outillage …

L’heure du bilan : qu’a apporté le BDD ?

© resonances-vs.ch/

Vous me direz, c’est bien beau tout ça, mais est-ce que c’est efficace ?

Très bonne question. Je rappelle les objectifs initiaux :

  • casser la défiance des équipes métiers vis-à-vis des équipes de la DSI,
  • faire comprendre aux équipes métiers les contraintes et problématiques de la DSI,
  • redonner du sens aux équipes techniques vis à vis de ce qu’elles produisent pour qu’elles s’investissent et s’approprient leur production

J’ajoute à ces objectifs des choses plus terre à terre tel que l’amélioration globale de la qualité des produits développés, la réduction du temps de conception d’une nouvelle fonctionnalité, la réduction du temps de maintenance de la documentation.

Amélioration des relations inter-équipes

Concernant la défiance, nous n’y sommes pas encore tout à fait. Il existe encore de grosses phases de recette métier après plusieurs itérations de développement et malgré tous les tests effectués par l’équipe technique. Dans notre cas, il y a aussi une dimension organisationnelle : l’équipe n’a pas accès à un journaliste pour lui servir de Product Owner. Si nous nous cantonnons au PPO (Proxy Product Owner), alors il y a du mieux car il a gagné la compréhension des contraintes techniques à travers les échanges systématiques avec l’équipe technique.

Reprise de sens du travail de développement

Pour ce qui est de redonner du sens aux équipes techniques, c’est difficile de se prononcer, notamment sur la partie legacy qui n’évolue pas ou peu. Si on regarde les applications plus récentes et celles qui ont bénéficié des plus grosses évolutions, alors on peut dire que l’implication est supérieure. C’est encore plus flagrant sur les nouveaux développements lancés après la mise en place de la démarche BDD et qui bénéficient depuis le début de ses bienfaits.

Performance de l’équipe

Si on regarde les objectifs plus terre à terre, l’amélioration de la qualité est difficile à mesurer (d’ailleurs comment mesure-t-on la qualité ? Hightest et Brice Roselier proposent quelques pistes dans cet article). Ce que je peux dire c’est qu’il n’y a pas eu de dégradation car le journal est imprimé tous les jours. Il y a bien sûr des incidents de temps à autre mais rien qui n’empêche la sortie sur les rotatives.

A propos de la réduction du temps de conception d’une nouvelle fonctionnalité, j’ai du mal à quantifier s’il y a eu un progrès. Ceci est dû au fait que la méthode BDD demande un effort plus important que ce qu’ils pratiquaient auparavant. Elle apporte aussi une réalisation meilleure du premier coup. Mais comme les mises en production sont au mieux trimestrielles, l’équipe technique a le temps de faire les choses…

Le paramètre sur lequel on voit la plus grande amélioration est la maintenance de la documentation. Fini la spec qui mêle le besoin et la solution. Nous avons d’un côté la documentation des fonctionnalités exprimées du point de vue des utilisateurs, et de l’autre la documentation technique de la solution. Ainsi si l’implémentation de la solution change, la documentation fonctionnelle n’a pas à être touchée. Et dès le moindre changement fonctionnel, la documentation est mise à jour automatiquement. Ce qui permet aux membres de l’équipe de toujours avoir une référence documentaire à jour.

Conclusion

La mise en place d’une démarche BDD dans un contexte où le legacy est très majoritaire n’est pas une pratique évidente à mettre en oeuvre. Il faut une équipe volontaire, qui croit en la démarche et qui souhaite s’y investir. Car c’est un investissement. Et pas sur du court terme mais plutôt sur du moyen-long terme, le temps de reprendre petit à petit un existant qui peut être conséquent.

Des questions restent toujours ouvertes (traçabilité des changements, granularité des scénarios, …) et les axes d’amélioration sont encore nombreux. Ce qui est sain et encourageant car c’est un signe que les personnes qui intègrent la démarche sont pleinement investis !

Sachez profiter des événements qui seront un terreau bénéfique à la mise en place de la méthode.

Préparez le terrain avec des formations, des ateliers pour accompagner les équipes dans ce changement.

Chaque équipe est différente, adaptez-vous !

Identifiez les relais dans les équipes qui porteront au quotidien la démarche.

 

Merci à Florent Vaution de Ouest-France pour ce témoignage inspirant, et bon courage aux QA qui se lancent ou se démènent déjà pour mettre en place une démarche de BDD dans leur organisation !

Crédit image couverture : © Ouest-France

Comprendre le BDD : table d’orientation en 9 questions-réponses

Le Behavior Driven Development : vous connaissez « de nom, de loin, vite fait », ça a l’air bien mais il vous manque des précisions. Cet article est votre chance d’y remédier !

Si le BDD fait déjà partie de votre quotidien, vous trouverez peut-être aussi des points de clarification, ou des éléments historiques qui donneront de la profondeur à votre pratique.

D’excellents articles ont été écrits sur le sujet et pour la plupart des questions il vous sera proposé d’en consulter ailleurs sur le web. Cet article est donc une table d’orientation, plutôt qu’un article de fond sur le sujet.

Bonne lecture !

Qu’est-ce que le BDD ?

Si vous découvrez tout juste le BDD et souhaitez avoir les notions de base bien en tête, nous vous conseillons avant tout de faire un tour sur cet article, qui pose bien le décor. Vous verrez que, même s’il date de 2012, il n’a pas pris une ride !

Qui doit piloter la démarche BDD ?

Bonne question ; le BDD est-il du ressort des développeurs ou du métier ? Dans la vidéo « Comment échouer un projet en BDD », Vincent Pretre (CucumberStudio, anciennement HipTest) explique comment son entreprise a échoué dans chacune de ces deux approches.

Spoiler : malgré ces deux échecs, l’histoire se termine (très) bien.

Quels sont les différences entre BDD, TDD et ATDD ?

Cette question est un véritable marronnier de la blogosphère du test…

Entre BDD et ATDD

Sur la différence entre BDD et ATDD, nous vous invitons à consulter cet excellent article de Marc Hage Chahine sur La Taverne du Testeur. Vous verrez qu’elle est relativement ténue et qu’elle invite au débat.

De manière générale, vous trouverez pas mal d’articles qui se démènent à trouver la différence entre ces deux approches.

Dans leur ouvrage More Agile Testing, Janet Gregory et Lisa Crispin détaillent les deux, tout en indiquant que, de même qu’avec la méthode SBE (Specification By Example), “il s’agit avant tout de commencer par des exemples et des conversations” (p. 148).

Entre BDD et TDD

La différence entre BDD et TDD est bien plus nette. Le TDD est avant tout une méthode qui concerne les devs, et le test ici est avant tout un test unitaire. Une équipe de développement pourrait très bien se mettre au TDD d’un jour à l’autre, sans que l’équipe de test ne s’en rende compte (ou alors indirectement, en constatant une raréfaction des régressions !).

Le TDD se matérialise par une routine en trois phases :

·        La rédaction d’un test unitaire de sorte à ce qu’il soit en échec (il vérifie quelque chose qui n’a pas encore été implémenté)

·        La rédaction du code afin que le test unitaire soit au vert

·        Le remaniement (ou refacto) du code afin de consolider, entre autres, sa maintenabilité. Et on revient si besoin à l’étape 1 pour préparer une nouvelle vérification !

Rien à voir, donc, avec le BDD et l’ATDD qui mobilisent aussi bien les devs que les QA et le PO. Pour autant, BDD et TDD sont bel et bien liés, car l’inventeur du BDD pratiquait le TDD au quotidien, et a voulu aller plus loin. Pour bien assimiler l’essence du BDD, il est donc intéressant d’avoir en tête le contexte dans lequel cette méthodologie a été fondée.

Ce qui nous amène à la question suivante…

Quelles sont les origines du BDD ?

Les bases du BDD ont été posées en 2003 par Dan North, celui qui sera amené à inventer le framework JBehave. A l’époque, la notion de TDD existait déjà depuis 4 ans. Elle portait ses fruits mais des problèmes subsistaient, notamment au niveau de la communication des attendus fonctionnels.

L’histoire de la naissance du BDD est contée dans cet article de Dan North (si vous préférez la version française, c’est ici).

Un résumé de l’histoire du BDD

Un premier déclic a eu lieu lorsque Dan North a commencé à utiliser Agiledox, un utilitaire développé par un de ses collègues, qui consistait à transformer des noms de méthodes en langage naturel. Un moyen bien pratique de générer des documents utiles à toute l’équipe.

Puis, de fil en aiguille, il a commencé à modifier les titres de ses tests unitaires en y introduisant le mot « should ». Il a remarqué que cette notion éveillait bien plus de remarques pertinentes (“Ca doit faire ça ? Mais pourquoi ?”) que l’austère notion de test.

Il a ainsi remarqué que la notion de “test” pouvait être trompeuse et ambiguë, alors que la notion de comportement parlait bien plus à l’ensemble de l’équipe. En parlant davantage de comportements que de tests, pas à pas, les blocages qui résistaient au TDD se sont levés. La méthode s’est étendue hors de la sphère du développement pour conquérir aussi l’analyse métier.

Le BDD était né !

Il y a donc un lien fort entre TDD et BDD. Et comme le dit si bien l’article du blog d’Arolla, « De manière un peu caricaturale, le BDD va guider le développement d’une fonctionnalité, tandis que le TDD guidera son implémentation. »

Ce que cette histoire nous apprend

L’histoire du BDD telle que racontée par Dan North est intéressante à plusieurs niveaux.

Premièrement, parce qu’elle retrace précisément toutes les étapes qui ont mené progressivement à l’émergence du BDD. C’est rare d’avoir une genèse qui aille autant dans le détail.

Deuxièmement, parce qu’elle est racontée avec beaucoup d’humilité et qu’on comprend que le BDD a été inventé grâce à une combinaison de contextes, d’outils et de personnes, et non pas du fait d’un éclair de génie de Dan North tout seul dans son bain.

Troisièmement, parce qu’elle illustre la difficile quête de la simplicité. Il est bien facile en 2020 de lire cette histoire en se disant « Finalement, ce n’était que du bon sens ». Le chemin devait être fait une première fois à petits pas avant de former l’autoroute dont on profite aujourd’hui.

Qu’est-ce que le langage BDD ?

Attention, le BDD n’est pas un langage, c’est une méthodologie !

Et la structure « Given / When / Then » (GWT) est simplement un canevas pour formaliser un comportement voulu, pas un langage en tant que tel. Bref, pour parler de manière exacte, il vaut mieux éviter de parler de langage BDD.

La structure GWT semble être ce qu’on retient le plus facilement du BDD, et elle est parfois utilisée comme raccourci pour présenter le BDD à une personne néophyte. Et donc, par abus de langage, on peut donc parfois entendre « un test en langage BDD ».

L’habit BDD fait-il le moine ?

Comme l’explique très bien Vincent Pretre dans la vidéo évoquée précédemment « Comment échouer un projet en BDD », ce n’est pas parce qu’on utilise le formalisme GWT qu’on fait du BDD, et inversement certaines équipes travaillant en BDD n’utilisent pas ce formalisme. Il fait un parallèle très parlant avec l’utilisation des post-its, qui n’est en aucun cas un gage d’agilité, même si cet artefact est largement représenté dans les images d’Épinal de l’agilité.

Quels sont les types d’outils de BDD ?

Les outils de BDD constituent un « passe-plat » efficace entre script et langage naturel. Mais… dans quel sens ? Dans un billet de blog de la décennie précédente (mais qui n’a pas non plus pris une ride), Jonas Bandi différencie deux types d’outils de BDD :

·        Ceux dont l’output est en langage naturel (là, l’équipe de développement est un peu le centre de gravité de la démarche BDD)

·        Ceux dont l’input est en langage naturel (là, toutes les personnes liées au projet peuvent être impliquées de la même façon)

La façon dont on souhaite travailler va donc avoir un impact majeur sur l’outil ou la chaîne d’outils choisie.

Le framework JBehave, initié par Dan North, permet d’utiliser les termes Given, When et Then en tant qu’annotations Java. Ce sont les rapports de test qui sont en langage naturel. Cet outil appartient donc à la 1ère catégorie. Le principe est similaire dans le framework Spock (oui, comme le Spock de Star Trek !)

Gherkin, intégré au framework Cucumber, est une syntaxe utilisant la structure GWT, avec une panoplie d’autres mots-clés. Les comportements sont exprimés en langage naturel, avec des fonctionnalités comme des tableaux de jeux de données. On est là dans la 2ème catégorie.

Cette typologie montre bien à quel point le formalisme GWT ne suffit pas à déployer une démarche BDD. Si on vise une collaboration inter-équipes (la philosophie même du BDD), on va avoir tendance à préférer un outil de la deuxième catégorie.

On pourrait même en arriver à penser que certains outils dits de BDD pourraient présenter un risque de nous éloigner des principes du BDD. A méditer…

Et en français, ça donne quoi ?

Libre à vous de développer l’usage de l’expression « Programmation pilotée par le comportement », même si elle n’est pas très usitée !

Pour info, le syllabus ISTQB niveau Fondation – Agile Tester s’éloigne un petit peu de la traduction littérale et parle de « Programmation pilotée par les tests de comportement ».

Est-ce possible de mettre en place le BDD sur un projet existant ?

La question se pose effectivement, mais sachez que la transition vers le BDD n’est pas évidente non plus sur un nouveau projet. Des aspects relevant de la culture d’entreprise et des interactions personnelles sont en jeu, ce n’est pas seulement une histoire d’outils ou de process.

Pour ce qui est des projets existants, cela ne coule a fortiori pas de source, mais ce n’est pas impossible. Dans le prochain article, notre invité Florent Vaution vous parlera de son expérience chez Ouest-France, où il a mis en place une méthodologie BDD dans un contexte legacy. Préparez-vous, ça va être passionnant !

 

Les Relative Locators de Selenium 4 : cas d’usage

16 ans déjà que Selenium existe ! Première version en 2004, Selenium 2 en 2011, Selenium 3 en 2016, et depuis le printemps 2019 il est déjà possible de s’amuser avec Selenium 4. Toujours en version alpha en février 2020, cette nouvelle mouture propose entre autres une nouvelle manière d’identifier les éléments d’une page web : les Relative Locators. Vous qui avez à coeur de faire de la veille sur les outils de test automatisé, c’est le moment de découvrir cette nouvelle fonctionnalité !

Que sont les Relative Locators ?

Vous connaissiez déjà les multiples manières proposées par Selenium pour identifier les objets : par attribut « id » ou « name », par « tag » (balise HTML), par xPath et par sélecteur CSS.

En plus de ces différentes manières, il est désormais possible de sélectionner des élément en fonction de leur position par rapport à d’autres éléments. Par exemple : l’image qui se trouve en-dessous du menu, le lien qui se trouve à gauche du logo, le bouton qui se trouve près (moins de 50 pixels) du footer. Seul l’élément par rapport auquel on se positionne nécessite un sélecteur ; pour l’élément cible, on n’indique que le nom de sa balise HTML.

Exemple de Relative Locator

// Avant
WebElement imageEnDessousDuMenu = driver.findElement(By.xpath("//div[@id=’menu’]//..//img")); // Ca ne vérifie pas que l’image est en-dessous du menu, juste qu’ils ont le même parent, par exemple une div

// Après
WebElement imageEnDessousDuMenu = driver.findElement(withTagName("img").below(By.id("menu")));

Les Relative Locators devaient d’abord s’appeler « Friendly Locators », et on comprend pourquoi : en intégrant dans le framework des notions visuelles, le code peut devenir plus simple à lire.

Sans vouloir jouer les trouble-fêtes…

Pour autant, nous n’avons pas réussi à nous souvenir de cas où ces localisateurs nous auraient vraiment sauvé la vie. Jusqu’à présent, nous avons toujours pu trouver des solutions satisfaisantes et robustes se basant sur les localisateurs historiques. Alors, les Relative Locators seraient-ils un ajout « sympa mais pas si utile » ?

Peut-on maintenant vérifier la position des éléments ?

Alors… si, il y a bien quelque chose qui pourrait être très utile : ce serait de vérifier la position relative d’un élément par rapport à un autre.

Comment ça, ce n’est pas ce qu’on vient de faire ?

Hé non, pas tout à fait. Certes, à chaque fois que notre code Selenium interagit avec un élément, cela nous permet de savoir qu’il existe. Pour autant, si le localisateur de notre « imageEnDessousDuMenu » renvoie une erreur « NoSuchElementException », on ne saura pas si c’est parce qu’il n’y a pas d’image sur la page, si le menu a changé d’ID, ou s’il y a bien la bonne image mais qu’elle n’est plus en-dessous mais au-dessus. Et parfois, on a besoin de savoir précisément si tel élément est bien situé par exemple à un autre. Par exemple, quand on teste le caractère responsive d’une page web.

Nous pensions que Selenium 4 arriverait avec des méthodes pratiques facilitant les assertions, du genre isElementBelow(WebElement unAutreElement), mais ce n’est pas (encore ?) le cas.

Cependant, il est bien sûr possible de s’en sortir avec des méthodes sur mesure.

Ce qui nous amène à notre exemple de mise en application !

Test de position des éléments avec Selenium 4

Cas d’usage : plein écran et demi-écran

Je visite le site https://service-public.nc/ depuis mon ordinateur portable, dont le système d’exploitation est Windows 10. La fenêtre de mon navigateur est au maximum. Ce que je lis est intéressant, je voudrais prendre des notes : je fais basculer mon navigateur en mode demi-écran, pour avoir le bloc-notes sur l’autre partie de l’écran.

Sur la page d’accueil du menu « Particuliers », en plein écran, les blocs se présentent ainsi :

En responsive, les blocs se réorganisent. Je souhaite évidemment que les éléments du site soient visibles et cohérents dans les deux affichages.

Vues différenciées

Vue desktop

Vue « demi-desktop »

Assertions à faire

Dans notre test automatisé Selenium 4, nous allons vérifier les assertions suivantes.

En mode desktop :

  • Le titre « Particuliers » est au-dessus de l’article 1
  • Le titre « Particuliers » est à la même abscisse (X) que l’article 1
  • Le titre « Particuliers » est à la même ordonnée (Y) que le bloc « Vos services en un clic »
  • Le titre « Particuliers » est à gauche du bloc « Vos services en un clic »
  • L’article 1 est à la même ordonnée (Y) que l’article 2
  • L’article 1 est à gauche de l’article 2.

En mode « demi-desktop » :

  • Le titre « Particuliers » est au-dessus de l’article 1 (ça ne change pas)
  • Le titre « Particuliers » est à la même abscisse (X) que l’article 1 (ça ne change pas)
  • Le titre « Particuliers » est au-dessus du bloc « Vos services en un clic »
  • Le titre « Particuliers » est à la même abscisse (X) « Vos services en un clic »
  • L’article 1 est au-dessus de l’article 2
  • L’article 1 est à la même abscisse (X) que l’article 2.

Allez, c’est parti !

Des méthodes de bas niveau pour vérifier la position des éléments

A gauche, à droite en haut ou en bas ?

A l’aide d’un enum, on liste seulement deux possibilités, histoire d’homogénéiser les choses dès le début. On n’a pas envie de se demander si c’est le menu X qui est à gauche du formulaire Y ou si c’est le formulaire Y qui est à gauche du menu X…

    public enum POSITION {
        A_GAUCHE_DE,
        AU_DESSUS_DE
    }

On utilise ensuite cet enum dans une méthode de bas niveau. Attention, cette méthode utilise l’objet « Selecteur » ; vous ne le connaissez peut-être pas encore, mais nous vous recommandons d’en créer un pour vos projets (pour plus d’infos, rendez-vous sur ce précédent article, qui explique les avantages du Selecteur).

On vérifie 3 choses dans cette méthode :

  • Premièrement, que les deux éléments existent
  • Deuxièmement, qu’il y a au moins un élément du même type que l’élément 1 dans la position souhaitée par rapport à l’élément 2
  • Troisièmement, que l’élément 1 fait partie de ces éléments

A chaque vérification son message d’erreur spécifique.

Attention, la méthode ne vérifie pas si l’élément 1 est le seul à répondre au critère, ni s’il est le plus proche. A vous de voir si ce niveau de contrôle vous suffit, ou si vous souhaitez le renforcer.

    public void verifierPosition(String tagElement1, Selecteur element1, POSITION position, Selecteur element2){
        // Vérification 1
        Assert.assertTrue(element1.getNom() + " aurait dû être présent(e)", driver.findElements(element1.getChemin()).size() != 0);
        Assert.assertTrue(element2.getNom() + " aurait dû être présent(e)", driver.findElements(element2.getChemin()).size() != 0);

        // Vérification 2
        List<WebElement> elementsMemeTypeMemePositionRelative = null;
        if(position == POSITION.A_GAUCHE_DE) {
            elementsMemeTypeMemePositionRelative = driver.findElements(withTagName(tagElement1).toLeftOf(element2.getChemin()));
        } else if (position == POSITION.AU_DESSUS_DE) {
            elementsMemeTypeMemePositionRelative = driver.findElements(withTagName(tagElement1).above(element2.getChemin()));
        }

        Assert.assertTrue("au moins un élément " + tagElement1 + " aurait dû être présent à la position relative souhaitée (" + position.name() + ") par rapport à l'élément suivant : " + element2.getNom() + ")",
                elementsMemeTypeMemePositionRelative.size() >= 1);

        // Vérification 3
        WebElement webElement1 = driver.findElement(element1.getChemin()); //
        Assert.assertTrue(element1.getNom() + " aurait dû être affiché(e) dans la bonne position (" + position.name() + ") par rapport à l'élément suivant : " + element2.getNom(), elementsMemeTypeMemePositionRelative.contains(webElement1));
    }

Au passage, avez-vous repéré les méthodes Selenium 4, toLeftOf() et above() ? 🙂

Libre à vous ensuite de surcharger cette méthode de bas niveau afin d’améliorer la lisibilité de votre code :

    public void verifierElementAGaucheDe(String tagElement1, AbstractPage.Selecteur element1, AbstractPage.Selecteur element2){
        verifierPosition(tagElement1, element1, AbstractPage.POSITION.A_GAUCHE_DE, element2);
    }

    public void verifierElementAuDessusDe(String tagElement1, AbstractPage.Selecteur element1, AbstractPage.Selecteur element2){
        verifierPosition(tagElement1, element1, AbstractPage.POSITION.AU_DESSUS_DE, element2);
    }

Même abscisse ou même ordonnée

On commence encore d’abord par un enum pour déclarer les deux axes possibles :

    public enum AXE {
        ABSCISSE_X,
        ORDONNEE_Y
    }

On a encore 3 vérifications :

  • Les deux éléments existent
  • Il y a au moins un élément du même type que l’élément 1 qui ne soit ni à gauche ni à droite (ou ni en haut ni en bas) de l’élément 2
  • L’élément 1 fait partie de ces éléments
public void verifierMemeAxe(AXE axe, String tagElement1, AbstractPage.Selecteur element1, Selecteur element2){
    Assert.assertTrue(element1.getNom() + " aurait dû être présent(e)", driver.findElements(element1.getChemin()).size() != 0);
    Assert.assertTrue(element2.getNom() + " aurait dû être présent(e)", driver.findElements(element2.getChemin()).size() != 0);

    List<WebElement> elementsMemeType = driver.findElements(withTagName(tagElement1));
    if(axe == AXE.ABSCISSE_X){
        // Là, on liste les éléments à gauche et à droite de notre élément (ceux qui ont un X différent)
        List<WebElement> elementsAGauche = driver.findElements(withTagName(tagElement1).toLeftOf(element2.getChemin()));
        List<WebElement> elementsADroite = driver.findElements(withTagName(tagElement1).toRightOf(element2.getChemin()));
        // On supprime de notre liste initiale tous les élements qui ont un X différent de notre élément
        elementsMemeType.removeAll(elementsAGauche);
        elementsMemeType.removeAll(elementsADroite);
    } else if (axe == AXE.ORDONNEE_Y) {
        List<WebElement> elementsAuDessus = driver.findElements(withTagName(tagElement1).above(element2.getChemin()));
        List<WebElement> elementsEnDessous = driver.findElements(withTagName(tagElement1).below(element2.getChemin()));
        elementsMemeType.removeAll(elementsAuDessus);
        elementsMemeType.removeAll(elementsEnDessous);
    }
    Assert.assertTrue("au moins un élément " + tagElement1 + " aurait dû être présent à la même " + axe.name() + " que l'élément suivant : " + element2.getNom() + ")", elementsMemeType.size() >= 1);
    WebElement webElement1 = driver.findElement(element1.getChemin());
    Assert.assertTrue(element1.getNom() + " aurait dû être affiché(e) avec la même " + axe.name() + " que l'élément suivant : "
            + element2.getNom(), elementsMemeType.contains(webElement1));
}

Et les méthodes « surchargeantes » :

    public void verifierElementMemeOrdonnee(String tagElement1, Selecteur element1, Selecteur element2){
        verifierMemeAxe(AXE.ORDONNEE_Y, tagElement1, element1, element2);
    }

    public void verifierElementsMemeAbscisse(String tagElement1, Selecteur element1, Selecteur element2){
        verifierMemeAxe(AXE.ABSCISSE_X, tagElement1, element1, element2);
    }

Résultat final !

On a désormais tout ce qu’il nous faut pour effectuer automatiquement les vérifications évoquées plus haut. Et les voilà, au sein d’un objet page (encore une fois si ce concept ne vous parle pas, rendez-vous sur cet article qui explique l’intérêt d’avoir des objets page) :

public class ServicePublicPage extends AbstractPage {

    private final Selecteur ongletParticuliersMenu = new Selecteur("l'onglet 'Particuliers' du menu", By.xpath("//a[contains(., 'Particuliers')]"));
    private final Selecteur titreParticuliers = new Selecteur("le titre 'Particuliers'", By.id("page-title"));
    private final Selecteur blocVosServices = new Selecteur("le bloc intitulé 'Vos services en un clic'", By.id("block-gnc-services-services-menu"));
    private final Selecteur blocSanteSocial = new Selecteur("le bloc intitulé 'Santé - Social'", By.xpath("//article[contains(., 'Santé - Social')]"));
    private final Selecteur blocTravail = new Selecteur("le bloc intitulé 'Travail'", By.xpath("//article[contains(., 'Travail')]"));

    public void accesPartieParticuliers(){
        clickElement(ongletParticuliersMenu);
    }

    public void verifierMenuDesktop(){
        driver.manage().window().maximize();
        verifierElementAuDessusDe("h1", titreParticuliers, blocSanteSocial);
        verifierElementsMemeAbscisse( "h1", titreParticuliers, blocSanteSocial);
        verifierElementMemeOrdonnee( "h1", titreParticuliers, blocVosServices);
        verifierElementAGaucheDe("h1", titreParticuliers, blocVosServices);
        verifierElementMemeOrdonnee( "article", blocSanteSocial, blocTravail);
        verifierElementAGaucheDe( "article", blocSanteSocial, blocTravail);
    }


    public void verifierMenuDesktop_demiEcran(){
        driver.manage().window().maximize();
        int largeurEcran = driver.manage().window().getSize().width;
        int hauteurEcran = driver.manage().window().getSize().height;
        driver.manage().window().setSize(new Dimension(largeurEcran/2, hauteurEcran));
        verifierElementAuDessusDe("h1", titreParticuliers, blocSanteSocial);
        verifierElementsMemeAbscisse( "h1", titreParticuliers, blocSanteSocial);
        verifierElementAuDessusDe("h1", titreParticuliers, blocVosServices);
        verifierElementsMemeAbscisse( "h1", titreParticuliers, blocVosServices);
        verifierElementAuDessusDe( "article", blocSanteSocial, blocTravail);
        verifierElementsMemeAbscisse( "article", blocSanteSocial, blocTravail);
    }

}

Maintenant, vous n’avez plus qu’à utiliser ces méthodes dans vos tests !

public class testServicePublicNC extends AbstractTest {

    @DisplayName("Vérifier l'ordre du menu en mode desktop")
    @Test
    public void verifierOrdreMenu_desktop(){
        ServicePublicPage servicePublicPage = new ServicePublicPage();
        servicePublicPage.accesPartieParticuliers();
        servicePublicPage.verifierMenuDesktop();
    }

    @DisplayName("Vérifier l'ordre du menu en mode desktop - demi-écran")
    @Test
    public void verifierOrdreMenu_desktop_demiEcran(){
        ServicePublicPage servicePublicPage = new ServicePublicPage();
        servicePublicPage.accesPartieParticuliers();
        servicePublicPage.verifierMenuDesktop_demiEcran();
    }

}

Bonus : si vous devez attendre avant de monter de version

N’oublions pas que Selenium 4 est encore en version Alpha. En attendant qu’une version stable soit livrée, et si vous en avez besoin dans vos projets actuels, il est déjà possible de réaliser les vérifications évoquées dans l’article. Cet article fournit un tutoriel très clair, en Java également.

Repenser les tests automatisés : un atelier collaboratif

Les longs récits de conférence n’intéressent personne, nous ne vous dirons donc pas à quel point TestBash Australia 2019 a été stimulant, merveilleux et inspirant ! En revanche, nous voudrions partager avec vous un atelier proposé à cette occasion par Mark Winteringham (merci à lui !), et que vous pourriez avoir envie de réaliser avec votre équipe.

L’idée de cet atelier est de mettre en lumière les différentes représentations que l’on a des tests automatisés. C’est un travail collectif qui permet de se rendre compte des images, attentes, déceptions et points de blocages liés à l’automatisation des tests. Des pensées qui bien souvent nous habitent sans que nous en ayons conscience ! Selon nous, il s’agit d’une démarche très intéressante, et nous comptons déjà cet atelier parmi les outils phares de l’automatisation des tests.

La théorie des médias et sa tétrade

La théorie des médias de Marshall McLuhan est à la base de cet atelier. Disons d’abord quelques mots là-dessus pour ne pas se perdre dans les concepts !

Qu’est-ce qu’un média ?

Ce terme peut être compris de trois manières différentes :

  • Les médias comme moyens de diffusion d’information
  • Les médias comme techniques et matériaux qu’utilise l’artiste pour créer
  • Les médias comme l’ensemble des techniques et objets qui modifient notre façon d’interagir avec le monde, en étant une sorte de prolongement de nous-mêmes. Ça englobe énormément de choses ! Les cuillères, les jeux de société, les alphabets. Et tout ce qu’englobent les deux précédents points. En fait, il ne nous semble pas maladroit de dire que « média » peut être compris comme « outil » au sens large.

C’est la troisième acception du terme qui est à l’œuvre dans l’atelier de Mark Winteringham.

Les quatre axes de lecture d’un medium

Dans Laws of Media: The new Science (publié en 1988), Marshall McLuhan considère que les médias (ou outils) comportent tous 4 problématiques.

En effet, chaque média :

  • Propose une extension, une amélioration.
    • Par exemple, un blog améliore notre capacité à partager nos idées, nous donne de nouvelles occasions d’échanger avec des personnes intéressantes, nous permet de figer et de pérenniser une réflexion à un instant donné.
  • Rend quelque chose obsolète.
    • Dans certains cas, les blogs rendent obsolètes les longs circuits de relecture et de validation qui peuvent exister dans le monde de l’imprimé, car si une coquille est constatée dans un article, elle peut être corrigée immédiatement.
  • Ramène à nous un média plus ancien, éveille des représentations.
    • La blogosphère pourrait rappeler par exemple la circulation des idées dans les salons du XVIIIème siècle.
  • Produit l’effet inverse à celui escompté lorsqu’il est poussé à l’extrême.
    • Si tout le monde passe son temps à produire de nouveaux articles de blog, plus personne n’a le temps de lire ou de s’intéresser à ce qu’écrivent les autres ; la notion de réseau disparaît.

Ces quatre problématiques sont schématisées par une tétrade.

Les automates de test : un média comme les autres ?

L’objet de l’atelier de Mark Winteringham est de questionner les automates de test en tant que média.

Déroulement de l’atelier

Pendant quelques minutes, par petits groupes de réflexion, on écrit sur des post-its des aspects de l’automatisation des tests répondant aux questions suivantes :

  • Que nous apporte l’automatisation des tests ?
  • Qu’est-ce que l’automatisation des tests rend obsolète ?
  • Que nous évoquent les tests automatisés ?
  • Lorsqu’elle est poussée à l’extrême, en quoi l’automatisation des tests produit-elle l’effet inverse à celui escompté ?

A l’issue de ces quelques minutes d’échange en petit groupe, chaque partie de la tétrade est traitée collectivement. Chaque groupe explique aux autres les points qu’il a relevés, et le débat se poursuit collectivement.

Les tests automatisés au prisme de la tétrade

Apports de l’automatisation des tests

In abstracto, il est difficile d’innover sur le premier point, qui donne d’ailleurs déjà lieu sur le web à une infinité d’argumentaires plus ou moins teintés de velléités commerciales.

En revanche, au sein d’un contexte dédié, cela a beaucoup de sens de s’interroger sur ce qu’apportent au quotidien les tests automatisés.

L’obsolescence induite par les tests automatisés

Le deuxième point, la question de l’obsolescence, questionne sur la vision « avant / après » ; quelles pratiques, artefacts et pensées ont disparu depuis la mise en place de l’automatisation des tests ? On s’interroge sur ce que l’automatisation vient remplacer.

L’imagerie de l’automatisation des tests

Le troisième point se démarque des autres car il est question avant tout de représentations. Il est intéressant de se demander quelles images font surgir les tests automatisés. Voyez-vous l’automatisation des tests comme une armée de robots rebelles dont vous êtes responsable ? Ou bien comme un tableau de bord comme ceux qu’on voit dans les vaisseaux spatiaux de films de science-fiction ? Il est possible aussi que l’automatisation des tests change la vision que vous avez de vous-mêmes. Prenez le temps de vous interroger sur toutes ces représentations que vous pouvez avoir.

Le côté obscur des tests automatisés

Sans surprise, c’est le dernier point qui a suscité le plus de réflexions intéressantes. Il permet d’identifier ou d’anticiper les pièges qui jalonnent les projets d’automatisation des tests. L’exercice de pensée consistant à pousser au maximum les caractéristiques du médium jusqu’à ce que ses avantages deviennent des inconvénients est particulièrement stimulant. Cela nous a rappelé entre autres la logopathie, l’automatite et la scalophobie (vous vous souvenez peut-être de ces maladies imaginaires du testeur automaticien…)

A vous de jouer !

Par choix, nous n’en disons pas plus sur les éléments qui sont ressortis de cet atelier à Sydney ; maintenant c’est à vous de jouer et nous ne voudrions pas influencer vos découvertes !

Encore une fois, merci à Mark Winteringham pour cet atelier très intéressant et pour nous avoir fait découvrir un concept sociologique très enrichissant. Merci aussi à toute l’équipe de TestBash Australia 2019 d’avoir réuni à Sydney de très grands testeurs et mis à disposition des contenus de la meilleure qualité.

Bonus : l’équipe de test comme média

La théorie des médias de McLuhan est un outil particulièrement fécond pour questionner les outils et leurs pratiques. Nous avons trouvé sur le web un article qui questionne la notion d’équipe de test à la lumière de cette théorie. Une lecture très intéressante (en anglais) que nous vous conseillons.

Bonus 2 : Marc Winteringham est l’auteur d’un site web (anglophone) riche en ressources sur le test logiciel et que nous vous invitons à consulter.

Crédits images : Merosonox (pour le schéma de la tétrade)

8 punchlines à l’usage des testeurs

How Google Tests Software (de James Whittaker, Jason Arbon et Jeff Carollo, 2012) est à nos yeux un ouvrage de référence. Il ne s’agit certes pas d’un référentiel de pratiques de test à appliquer à la lettre, mais nous avons été agréablement surpris de voir qu’il regorge d’idées intéressantes pouvant être adaptées à des entreprises de toutes les tailles. Ce qui nous a d’ailleurs inspiré un article sur les plans de test.

Ce livre peut être appréhendé comme une photographie des processus de test de Google à un instant T. Un instant déjà lointain, et pourtant bon nombre d’idées vous sembleront venues du futur ! Il est également truffé de bons mots, dont certains que nous avons choisi de partager avec vous dans cet article. A méditer sans modération !

A noter : les traductions sont de notre cru.

Sur la qualité

« La qualité doit être intégrée au logiciel, et non pas boulonnée par-dessus. Dans cette mesure, elle est du ressort du développeur. Point. » p. 229

« Quand le test devient un service qui permet aux développeurs de ne pas penser à la qualité, alors ils ne pensent plus à la qualité. » p. 230

Ces punchlines résument bien la vision du testeur portée par cet ouvrage : celle d’un facilitateur de la qualité, qui partage intelligemment le fardeau de cette responsabilité. Une vision agile par excellence.

Sur l’état d’esprit du testeur

« Les testeurs mettent en avant leur rôle, et non pas le produit sur lequel ils travaillent. Et dès lors qu’on détourne son attention du produit, celui-ci en pâtit. Après tout, le but ultime du développement logiciel est de construire un produit, pas de le développer, de le tester ou de le documenter. […] Les utilisateurs tombent amoureux de produits, pas des processus qui ont permis de le construire. » p. 230

Dans cette logique, les auteurs considèrent que pour se présenter professionnellement, « Je travaille sur Chrome » est une affirmation plus saine que « Je suis testeur ».

Sur les livrables de test

« Les développeurs ont un avantage clé sur les testeurs en ce que tout le monde s’intéresse aux artefacts qu’ils produisent. » p. 79

Elle pourrait être lue comme un constat grinçant, mais cette phrase est simplement un rappel de bon sens. Elle implique entre autres qu’en tant que communicant, le testeur doit se tenir à une exigence de concision. Les livrables de test doivent être avant tout opérationnels et les plus digestes possible. Cela rejoint la punchline précédente, on doit avant tout travailler au service du produit, la « beauté » de nos tests n’a pas d’importance.

Dans le même esprit, on retrouve :

« Un plan de test qui n’aboutit pas directement à des cas de test est une perte de temps. » p. 82

Sur les rapports d’anomalies

« Les bugs sont comme des gamins couvés par leurs parents. […] De même qu’un papa ou une maman sort son thermomètre, le testeur prépare ses outils. Un parent veut faciliter le diagnostic de la maladie de son enfant. Une mère veut faire comprendre au docteur à quel point son petit est mal en point. Un testeur veut faire connaître la criticité du bug, et plus encore, le rendre facile à corriger. » p. 126

Voilà une tendre comparaison à opposer aux esprits chagrins qui considèrent que le test est une activité destructrice… Elle est issue d’un encart très intéressant nommé « It’s a Bug’s Life ». Encore une puissante métaphore (voir notre série sur ce sujet) qui pourrait aider à faire changer la perception que beaucoup de gens ont des testeurs !

Sur les tests manuels

« ‘Pourrai-je bientôt me passer du test manuel ?’ Notre réponse est un non catégorique. [La mise en place de l’automatisation des tests] permet simplement aux testeurs de faire enfin le travail pour lequel ils ont été recrutés : des tests exploratoires bien pensés, de l’analyse des risques, et une réflexion orientée utilisateur. » p. 152

S’il fallait mettre un dernier clou au cercueil de cette idée reçue (« Les robots vont tester à la place des testeurs, youpi ! »), voilà une punchline qui pourrait vous inspirer. On la doit à Tejas Shah, alors à la tête d’un projet d’automatisation des tests pour Chrome.

Sur les risques

« Assurément, ne pas livrer un logiciel n’est pas une option, bien qu’elle représente un risque d’échec inexistant. Une entreprise tire profit de risques correctement estimés. » p. 97

Bref, nous ne pouvons que vous conseiller la lecture de cet excellent ouvrage, et nous espérons que ces quelques amuse-bouche vous auront donné envie de le lire. Qui sait, peut-être voudrez-vous l’offrir à un de vos collègues pour Noël ?

[Invité] L’épineuse question des KPI

Nous avons le plaisir de vous dire que cet article a été écrit à quatre mains, avec Brice Roselier. Expérimenté en test, il a mis en place des KPI afin de suivre la progression de la qualité des activités de test dans son contexte.

Comment communiquer sur la qualité des tests ? Quels indicateurs de performance produire ? Comment suivre l’évolution de ces indicateurs ? Nous abordons ces questions pour faire suite aux deux derniers articles, portant respectivement sur l’organisation du contrôle des tests et sur l’auto-évaluation de la qualité des tests.

Voilà en tous cas une épineuse question, et le sujet devient d’autant plus glissant lorsqu’il est motivé par des problématiques d’intéressement. Il a donné lieu à un passionnant débat il y a quelques mois sur LinkedIn, dans le groupe « Le métier du test » (si vous n’y êtes pas encore, c’est vraiment le moment de le rejoindre, ça représente plus de 3900 testeurs passionnés !).

Articles de la série :

  1. Organiser le contrôle des tests logiciels
  2. Auto-évaluer la qualité de ses tests
  3. L’épineuse question des KPI

Les métriques de la mort

Avant toute chose, et avant que vous ne fermiez cet onglet parce que votre collègue vous appelle sur un sujet plus urgent, voici une liste de KPI à ne jamais, jamais, jamais envisager. S’il vous plaît. Please. Por favor.

Le nombre de bugs créés

Vous voulez vraiment vous retrouver avec un gros paquet de bugs doublonneux ? Ou vous retrouver dans une situation horriblement paradoxale, où les testeurs auraient envie que l’application soit de mauvaise qualité…

Le nombre de cas de test écrits

Un référentiel de tests c’est comme une maison : tu peux y ajouter des objets, mais tu dois aussi te débarrasser de ceux qui t’encombrent et ne te servent à rien, lutter contre la poussière et ranger le mieux que tu peux.

Le nombre de scripts de tests automatisés

Bonjour la maintenance si vous optez pour ce KPI. C’est comme si un développeur était rémunéré à la ligne de code…

La durée des tests

« Nous visons à réaliser des campagnes de test qui durent moins de 8 heures. »

Quelle belle résolution, et quelle tentation de créer un KPI associé vu qu’il y a 3 semaines on a même tout bouclé en 7 heures. Hélas, encore une fois on se retrouve dans un champ de peaux de bananes. Les activités de test sont largement impactées par la qualité constatée de l’application à tester.

Comme le souligne Gerald M. Weinberg dans Perfect Software, and other illusions about testing (2008), si les testeurs trouvent un grand nombre de bugs et passent du temps à les analyser, l’avancement de leur campagne sera nécessairement ralenti. Pour autant, sans analyse, la plupart des rapports de bugs ne sont que de médiocres ânonnements.

Toutes les métriques citées sont intéressantes lorsqu’elles sont contextualisées, mais ne devraient pas être utilisées comme KPI au risque de se retrouver à faire de la « gonflette ». Comme le dit un de nos amis développeurs de Nouvelle-Calédonie, « No disco muscle boy, we want strength! »

Quelques prudentes suggestions

De manière générale, les KPI sont à définir en bonne intelligence avec les autres membres de l’équipe. Il faut en premier lieu garder en tête la grande différence qui existe entre une simple métrique et un véritable KPI, qui peut être une métrique à laquelle on attribue une valeur de performance, ou un ensemble de métriques consolidées.

Et de même qu’on distingue la notion de « Créer un produit bien fait » et de « Créer le bon produit », on peut distinguer d’une part la notion « Faire bien les tests » et « Faire les bons tests ».

Quelques pistes peuvent être réfléchies ensemble :

  • Les bugs non trouvés dans l’environnement de test, et qui sont remontés par des utilisateurs en production
    • Ça fait mal. Il faudrait aussi pouvoir s’assurer que le bug pouvait effectivement être trouvé en environnement de test. Ce n’est malheureusement pas toujours le cas… Ce KPI pourrait être remonté sous forme de ratio ou de valeur absolue, et être qualifié par exemple par le niveau de criticité du bug.
    • Avec ce KPI, on vérifie qu’on « fait les bons tests ».
  • La qualité des rapports d’anomalie
    • Toute la difficulté sera d’établir des critères objectifs et de trouver le meilleur moyen de mettre en place cette évaluation. Sera-t-elle attribuée par un représentant de l’équipe de développement ? Par un collège de développeurs ? Par le team leader des testeurs ?
    • Avec ce KPI, on vérifie qu’on « fait bien les tests ».
  • Le ratio de tests de régression d’importance haute automatisés versus non automatisés
    • Il est un peu moins facile de « tricher » avec ce chiffre, mais encore une fois attention à la gonflette…
    • Avec ce KPI, on vérifie également qu’on « fait bien les tests ».

Ce ne sont là que quelques exemples assez génériques, la définition des KPI devant prendre en compte les caractéristiques du produit, du projet et de l’équipe. Un grand sage disait : « Les tests dépendent du contexte »…

Suivre ses KPI à la trace

Une fois en place, les KPI doivent être suivis et exploités, c’est d’ailleurs tout leur intérêt. Pour des raisons de simplicité, cherchez à automatiser la relevée de vos KPI, de façon à les mettre à jour simplement et rapidement. En effet, pour suivre vos KPI, ceux-ci devront être régulièrement mis à jour. Le faire manuellement est à la fois un risque d’erreur, chronophage et surtout peu réjouissant !

Une fois que les KPI donnent une valeur, idéalement de façon automatique, vous devez vous en servir pour progresser. Posez-vous la question sur la façon dont vous exploitez les données brutes (les indicateurs), c’est-à-dire les unités de mesure et leur contexte. Par exemple, si votre KPI se base sur une charge en jours-hommes, est-ce que cette valeur représente le sprint en cours, la release, toute la période depuis le début du projet, ou bien le mois en cours, depuis le début de l’année ou même une période glissante (les 12 derniers mois) ? Il y a plusieurs moyens de faire parler vos indicateurs qui sont la matière première de vos KPI.

Ensuite, fixez-vous des objectifs, SMART de préférence, de façon à voir vos KPI embellir avec l’âge. Un objectif SMART est, comme l’indique cet acronyme, Spécifique, Mesurable, Acceptable (à la fois Ambitieux et Atteignable), Réaliste et Temporellement défini.

Je doute que le simple affichage de vos KPI ne vous satisfasse. Ces valeurs, vous voulez les voir évoluer car elles traduiront un progrès (ou pas) de votre processus de test et/ou de votre équipe. Pour cela, fixez-vous une valeur légèrement meilleure, et tentez de l’atteindre dans un délai relativement court. Cela vous donnera une idée de ce à quoi vous pouvez prétendre. Enfin, si vous souhaitez améliorer votre KPI sur la durée, planifiez un plan de progrès sur une période (par exemple augmenter la valeur de votre KPI de 10% en un an) avec des jalons intermédiaires qui vous mèneront à votre objectif.

Quelques exemples d’indicateurs et KPI

Dans un premier temps, listez les indicateurs que vous souhaitez suivre et réfléchissez à la manière dont vous allez les alimenter. A partir de là, alimentez vos indicateurs et KPI progressivement. Le piège étant, comme dit plus haut, qu’un indicateur puisse s’exprimer de plusieurs façons.

Tout le monde le sait, à court terme, le test est une charge qui augmente le budget d’un projet. Vous devez donc chercher à améliorer le ratio entre la qualité apportée par les tests et l’énergie à fournir pour atteindre ce résultat. Un peu à l’image d’un compte-tours, plus la vitesse est élevée et moins le moteur tourne rapidement, plus il est efficace.

A ce stade, c’est bien l’efficacité des tests que l’on souhaite mesurer et non la qualité intrinsèque de l’objet de test. Le tout étant de faire vivre les indicateurs et KPI dans le temps et chercher à améliorer le processus de test.

A titre d’exemple, voici ci-dessous la liste de quelques indicateurs que Brice suit chez lui.

Indicateurs liés aux anomalies

KPI associés : 

~ Anomalies détectées et confirmées / Anomalies non détectées

~ Anomalies corrigées / Anomalies non résolues

  • Anomalie non détectée (faux négatif) : un classique de chez classique. Ce sont les anomalies qui passent entre les mailles du filet. L’utilisateur remonte une ano que le test n’a pas vu. On le mesure sous forme de coefficient qui représente la somme du nombre d’anomalies pondéré par leur criticité (on peut imaginer un barème 1, 3 et 20 pour mineur, majeur, bloquant). Pour aller plus loin vous pouvez même chercher à mesurer la quantité d’utilisateurs concernés par ces faux négatifs.
  • Anomalies détectées et confirmées : on considère que l’anomalie n’est pas un faux positif et qu’elle n’est pas en doublon. Ici on ne se focalise pas sur la criticité, on compte simplement le nombre d’anomalies détectées via un test auto ou manuel.

Exemple de représentation des anomalies détectées :

Ici 2072 anomalies ont été détectées dont 64 critiques, 662 majeures et 1346 mineures.

Représentation de graphique représentant la provenance des anomalies détectées :

Exemple de graphique représentant la répartition des anomalies détectées par module :

  • Anomalies non résolues : ça arrive, ce sont les anomalies peu impactantes que l’on accepte d’avoir en production, car elles sont coûteuses à corriger, liées à un contexte très particulier pour les reproduire et qu’il n’y a pas assez de temps pour les traiter avant la sortie de la version. Cet indicateur permet d’estimer l’effort de correction à court terme et la confiance à la clôture des tests. Comme les faux négatifs, on l’exprime sous forme de coefficient en pondérant la criticité des anomalies. Cet indicateur donne en premier lieu une information sur la qualité du livrable, mais dans un second temps on peut avoir ici un axe d’amélioration du processus de test : les anomalies sont peut-être découvertes trop tard. Cela donne aussi une estimation pour la campagne suivante car les anomalies non résolues donneront lieu à des tests de confirmation.

Exemple de représentation des anomalies non résolues :

Dans cet exemple, depuis la première version de l’application, 650 anomalies n’ont pas été résolues, dont 16 critiques, 213 majeures et 421 mineures. En affectant un barème de 20 points pour une anomalie critique, 3 points pour une majeure et 1 point pour une mineure cela donne un coefficient global de 1380.

Exemple de graphique représentant la répartition des coefficients des anomalies non résolues :

  • Anomalies corrigées : nombre d’anomalies pondérées par leur criticité ayant été corrigées (sous forme de coefficient). Ici on cherche à mesurer l’amélioration de la qualité apportée grâce aux tests.
  • Faux positifs et doublons : avec cet indicateur, on va chercher à mesurer l’effort de test sans valeur ajoutée. C’est-à-dire ce qui génère du temps passé pour rien. On peut le mesurer sous forme d’entier positif et le mesurer en pourcentage par rapport au nombre d’anomalies détectées. 10 faux positifs sur 20 anomalies c’est beaucoup, pour 1000 anomalies c’est mieux !

Représentation de graphique représentant la provenance des faux positifs :

Indicateurs liés à la complétude des tests

KPI associé :

~ Couverture du code

  • Couverture du code : quantité du code exécuté au moins une fois pendant les tests. On cherche à mesurer la profondeur (in)suffisante des tests. On la mesure en pourcentage sur les fichiers, les lignes et les conditions couvertes. Cette couverture peut être calculée avec un outil d’analyse statique tel que SonarQube pour les tests unitaires, mais pas seulement. Chez Brice le code métier est en C, à la compilation peuvent être ajoutées des options pour générer des traces à l’exécution. En manipulant ces traces on peut donc calculer la couverture même sur du test système réalisé en boîte noire.
  • Couverture des exigences : mesure la profondeur (in)suffisante des tests et la confiance à la clôture des tests. Cela permet également de prioriser les tests. On l’exprime sous forme de pourcentage, qui correspond au nombre de tests en succès divisé par le nombre de tests rattachés à l’exigence.

Indicateurs liés à la capacité d’exécution des tests

Pas de KPI ici, ce sont des indicateurs fortement influencés par les développeurs et le contexte (si tous les testeurs sont malades, pas de test)

  • Quantité d’exécution cumulée : répartie sur chacun des niveaux de tests. On compte le cumul du nombre de fois qu’un test a été exécuté dans sa vie. Cela permet de mesurer la vélocité : le nombre moyen de tests qu’il est possible d’exécuter sur une campagne donnée.
  • Nombre de retests : moyenne des aller-retour entre les équipes de test et les développeurs. C’est en quelque sorte le nombre de fois qu’un développeur s’y est repris pour résoudre une anomalie. Derrière, ça veut dire que le testeur va consommer du temps pour retester, requalifier l’anomalie en expliquant pourquoi l’anomalie n’est toujours pas résolue, joindre des impressions d’écran, des logs etc. et quand même retester plus tard. Il faut aussi comprendre pourquoi une anomalie a été difficile à résoudre. La description de l’anomalie n’était peut-être pas claire ou insuffisante (on a trouvé le défaut dans un contexte mais il se retrouve aussi dans d’autres).
  • Quantité de régressions : on montre ici le niveau de maturité des tests de bas niveau et la suffisance en termes d’effort de test avant les niveaux supérieurs, mais ce qui nous importe le plus c’est de mesurer l’effort de test sur des articles qui ont été validés avant. On montre l’impact des modifications sur l’activité de test (test, analyse, retest, gestion de l’anomalie…).

Indicateurs liés au patrimoine de tests

Pas de KPI, ce sont des indicateurs sur les tests, pas de quoi soulever la coupe !

  • Taux d’automatisation des tests : répartition du nombre de tests automatisés dans le patrimoine. Tout comme le patrimoine, Brice cherche à suivre l’avancement de l’automatisation, ce qui donne une information sur la capacité à tester. Il représente toutefois une charge de maintenance à ne pas oublier (comme un test manuel) ; la qualité de la conception des tests automatisés impactera fortement cet effort de maintenance.
  • Tests sans anomalie : sur une campagne ou même sur un laps de temps, combien de tests n’ont trouvé aucune anomalie ? Ils peuvent questionner sur leur capacité à trouver de nouveaux défauts. Ces tests feront l’objet d’une revue à court terme, et seront peut-être obsolètes. On les mesure sous la forme d’un entier positif.
  • Volumétrie des tests : cet indicateur mesure quantitativement le patrimoine de test. Il peut être intéressant si aucun test n’est encore formalisé dans un outil. Il peut se mesurer sous la forme d’un entier positif pour chaque type de test (voir diversification des tests).
  • Diversification des tests : un petit indicateur qui exprime le nombre de types de tests implémentés dans le patrimoine de test : performance, fonctionnel, accessibilité, validation W3C etc. On l’exprime sous la forme d’un entier positif.

Indicateurs liés aux coûts des tests :

Pas de KPI, mais ces indicateurs sont comme le compte-tours du moteur

  • Charge de test : effort du processus de test (manuel et automatisation). Ça représente le coût total (humain) des tests. En d’autres mots, le temps total passé par les équipes sur des activités de test. On l’exprime en jours-hommes (que l’on peut ensuite multiplier par un TJM) et en ETP.
  • Charge d’automatisation : effort de test sur la partie automatisation, à savoir l’implémentation des scripts de test, le développement des briques (techniques et fonctionnelles), des étapes et des outils liés à l’automatisation. Cela permet de mesurer le coût d’automatisation des tests. Brice l’a découpée en 5 valeurs (respectivement pour 5 types d’activités dans l’automatisation) exprimées en jours-hommes.
  • Coût interne d’une défaillance : c’est la charge de correction d’une anomalie. Cela dépasse le périmètre de tests mais permet de prendre un peu de hauteur en mesurant tout ce qu’une anomalie détectée par l’équipe des testeurs implique dans le service y compris en conception et développement.
  • Coût de détection : c’est une extension de la charge de test à laquelle on ajoute les coûts de l’infra, les licences des outils, leur administration, leur maintenance etc.

Bibliographie

Pour clôturer cette série (déjà !), rien que pour vous, voici quelques ressources qui vous aideront à repenser la qualité de vos tests.

  • Miserere nobis patrimonium – Ayions pitié de notre patrimoine, un article du wiki Fan de test qui donne encore plus envie de s’y mettre.
  • Perfect Software, and other illusions about testing, Gerald M. Weinberg, 2008. Le chapitre 8 (« What makes a good test ? ») détruit les idées reçues sur la qualité des tests.
  • Dear Evil Tester, Alan Richardson, 2016. En particulier la partie « What is the most evil metric ? »
  • The way of the web tester de Jonathan Rasmusson, 2016. Cet ouvrage contient un grand nombre de bonnes pratiques de développement de tests fonctionnels automatisés (pour applications web). Peut-être pourra-t-il vous servir pour mettre en place en interne vos propres standards !
  • Test logiciel en pratique de John Watkins, 2001. Le chapitre 12 est dédié à l’amélioration du processus de test.

Auto-évaluer la qualité de ses tests

Dans notre article précédent, nous donnions des pistes pour organiser le contrôle des tests par des instances extérieures à l’équipe de test. En effet, il n’est pas rare d’avoir à rendre des comptes sur les activités de test, et cela peut même être une bonne opportunité pour roder un peu mieux ses pratiques.

A force de discussions, de réflexions, de compromis et d’idées merveilleuses, nous avons désormais un cadre de travail qui nous permet de communiquer sur les tests et d’indiquer la valeur ajoutée des différents livrables de l’équipe de test. Cependant, ce sont des indicateurs globaux, et qui témoignent a posteriori de la qualité du travail produit. Maintenant, comment « tester les tests » au plus tôt, de façon à ce que ces indicateurs soient toujours votre plus grande fierté ?

On quitte maintenant la sphère de la communication inter-équipes, pour rentrer dans le (très) vif du sujet, à savoir dans la passionnante popotte interne de l’équipe de test.

Articles de la série :

  1. Organiser le contrôle des tests logiciels
  2. Auto-évaluer la qualité de ses tests
  3. L’épineuse question des KPI

Chercher les failles des tests plutôt que valider leur qualité

Comme l’indique Gerald M. Weinberg dans Perfect Software, and other illusions about testing (2008), la qualité d’un test ne peut pas être démontrée. Un référentiel de tests excellent aura d’ailleurs, selon son exemple, le même résultat qu’un référentiel de tests « sale » après une campagne passée sur un applicatif totalement dénué de bugs. Scénario purement théorique bien sûr…

En réalité, de même que les tests révèlent la présence de défauts d’une application (premier principe du test logiciel), la revue d’un test ne peut pas révéler sa qualité.

Ce n’est que l’analyse a posteriori qui pourrait permettre de déduire le niveau de qualité des tests, notamment en tenant compte des bugs qui n’ont pas été détectés par les tests. Et encore, cette analyse ne serait jamais complète, car nous ne pouvons jamais savoir combien de bugs existent sans avoir été détectés.

Gerald M. Weinberg préconise, plutôt que simplement attendre de pouvoir faire cette analyse a posteriori, de :

  • revoir sa couverture et ses oracles en anticipant les erreurs
  • créer de la variabilité dans les tests existants
  • comparer en parallèle différentes façons de tester

Un poil diabolique, il raconte également, en tant que développeur, avoir gardé secret un bug pour voir à quel moment il serait détecté par l’équipe de test. A méditer !

En bref, il n’est pas possible de savoir si des tests sont bons, mais certains signes peuvent indiquer qu’ils ne le sont pas.

Une interrogation intériorisée par l’équipe…

Qui forme le formateur de formateurs de formateurs ? Qui relit le relecteur ? Qui coache le coach ?…

En tant qu’animateurs de la qualité, il appartient aux testeurs de toujours rester vigilants sur la qualité de leurs propres tests. Cela peut passer par des actions à mettre en œuvre dans son équipe :

  • Validation croisée des cas de test
  • Revue des scripts de tests automatisés, mise en place de bonnes pratiques de développement
  • Amélioration des cas de test pendant l’exécution des campagnes
  • Sessions de tests exploratoires
  • Révision des tests en regard des anomalies trouvées en-dehors des scénarios de test écrits
  • Maintenance et restructuration du patrimoine de tests

Tout cela vous semble évident ? Mais le faites-vous vraiment, ou seulement quand « il y a le temps » ? Ces activités sont-elles connues et reconnues par les autres parties prenantes ?

Ces validations internes peuvent donner lieu à des checklists permettant de valider tel ou tel livrable de test. Pourquoi ne pas imaginer également des Definition of Done spécifiques ?

Exemple de Definition of Done d’un ensemble de tests portant sur une exigence :

  • Les tests comptent à la fois des « Happy paths », des « Sad paths » et des « Ugly paths » (cas passants, cas non passants et cas « tordus »)
  • Les tests sont liés clairement à l’exigence dans un souci de traçabilité
  • Les métadonnées des tests sont correctement renseignées
  • Les jeux de données indiqués dans les tests sont facilement trouvables / facilement maintenables
  • Le vocabulaire utilisé est conforme au lexique approuvé par l’ensemble des acteurs du projet (comment ça, votre équipe n’a pas encore de lexique ? :D)
  • Les tests ont été révisés par un autre testeur
  • N’importe quel autre critère qui vous semblera à la fois pertinent et simple à vérifier.

Etudier également chaque cas de découverte de bug en production pourrait aussi permettre à l’équipe de test d’identifier ses lacunes et de les corriger. Cette démarche gagnerait à être explicite, et non expédiée honteusement comme un enfant qui cache sous un meuble les fragments de l’assiette qu’il vient de faire tomber…

… et par chaque testeur individuellement

Certes, les équipes de testeurs ne sont pas toujours suffisamment fournies pour organiser des activités internes de révision et de validation croisée des tests. Dans bien des cas, c’est au testeur que revient la tâche de « tester » ses propres tests. Dans cette mesure, la question « Comment teste-t-on les tests ? » devrait être intériorisée par le testeur lui-même, de façon à animer ses activités.

En somme, « Comment teste-t-on les tests ? » pourrait bien être une question à poser à un testeur lors d’un entretien d’embauche. Un mélange de savoir-faire (techniques adaptées de revue des tests) et de savoir-être (esprit critique, crainte du bug en prod, etc.) pouvant être attendus.

Dans notre prochain article, nous nous pencherons sur ce qui constitue peut-être le point le plus épineux de cette série (et il y en a eu !), à savoir les KPI.

A très vite !

Addendum – novembre 2020 : un mot sur le mutation testing

Tester les tests unitaires est possible grâce à une pratique que l’on appelle le mutation testing. Cela consiste à générer des changements aléatoires dans le code et à vérifier si les tests unitaires repèrent ces changements. Cela simule en fin de compte des régressions qui pourraient être introduites par du nouveau code ou un réusinage (refacto) maladroit. Des outils sont spécialisés dans ce type de test, par exemple Pitest.

Quoi de plus parlant pour illustrer l’intérêt des tests unitaires ?

Quelques ressources

Si vous n’avez qu’une minute à consacrer à ce sujet, ce post LinkedIn de Michaël Azerhad résume très bien, et avec un exemple pratique, l’apport de cette technique.

Si vous avez 10 minutes, offrez-vous la lecture de cette présentation de la JFTL 2019 signée Vincent Huc, Amandine Jaufeeraully et Marie Isoard.

Enfin, vous avez une heure entière, le visionnage de cette vidéo vous profitera. Il s’agit d’une conférence en anglais signée Sven Ruppert.

Merci à la communauté LinkedIn francophone de la qualité logicielle pour ces précieuses suggestions de lecture !

Organiser le contrôle des tests logiciels

On dit que les cordonniers sont les plus mal chaussés. Qu’en est-il des testeurs ; sont-ils les plus mal testés ?

De la qualité des tests découle en partie la qualité des applications. Une application de qualité est souvent une application qui a été bien testée. Les tests permettent d’avoir une idée de la qualité des applications, mais qu’est-ce qui permet d’avoir une idée de la qualité des tests ? En quelque sorte, comment tester les tests ?

Cette question peut être prise dans deux sens différents : d’une part, comment rendre compte de la qualité des tests à un interlocuteur extérieur à l’équipe de test (le présent article) ; d’autre part, comment s’assurer en tant que testeur que nos tests apportent la meilleure valeur ajoutée possible (l’article suivant !). Un troisième article traitera de l’épineux et passionnant sujet des KPI (Key Performance Indicators).

Une ligne directrice anime le contenu de ces articles : la prudence. Nous allons voir que le contrôle des tests est une activité hautement piégeuse.

Articles de la série :

  1. Organiser le contrôle des tests logiciels
  2. Auto-évaluer la qualité de ses tests
  3. L’épineuse question des KPI

Quand le contrôle devient contre-productif

Cette question de la qualité des tests, nous l’avons devinée derrière certaines pratiques en vigueur dans les organisations où nous sommes intervenus, parfois sous forme d’un reporting très rigoureux permettant le contrôle de l’exécution des tests. Nous allons voir que toutes les façons de « tester les tests » ne sont pas bonnes.

« Je veux voir tout ce que vous avez testé. »

Par exemple, dans une certaine organisation, des personnes en phase de recette donnaient des preuves très précises de leurs tests en réalisant des copies d’écran à chaque étape. En l’absence d’outillage, cela donnait lieu à d’interminables fichiers Word. Ces personnes produisaient donc une preuve tangible de la bonne exécution des tests… Mais cela occasionnait aussi une perte de temps abominable, pour avoir finalement un livrable très difficilement interprétable.

Ailleurs, d’autres prenaient l’initiative de créer un rapport de bug à chaque fois qu’ils reproduisent une anomalie. Une manière de matérialiser l’activité de test, alors qu’en réalité cette pratique se soldait par un long et fastidieux travail de dédoublonnage.

Ces formes de contrôle n’apportent pas vraiment de valeur, et permettent simplement de vérifier qu’à un moment donné, quelqu’un a suivi les instructions de scénarios de test quelconques.

Quel besoin derrière le contrôle ?

Ces pratiques peuvent en dire long sur la perception des tests, et témoigner peut-être de la vision courante selon laquelle les tests sont une activité improductive. On se retrouve alors face au souci de laisser une trace fidèle, relatant l’ensemble du parcours de test, pour justifier de cette activité auprès de la hiérarchie par exemple.

Cela peut aussi dénoter un manque de confiance dans l’équipe chargée des tests. Mais dans ce cas, à quoi ce manque est-il dû ? Le nombre de bugs trouvés est-il inférieur à ce à quoi on s’attendait ? Des bugs non détectés sont-ils passés en production ? Le contenu des activités de l’équipe de test semble-t-il opaque aux autres services ?

Bref, il est important de disséquer les intentions cachées derrière la demande de preuve de tests. La réponse à apporter sera sans doute alors différente d’un compte-rendu complet des activités de test.

La nécessaire liberté du testeur

Enfonçons le clou encore plus loin. Les outils de gestion des tests proposent des fonctions de reporting très précieuses pour donner des indications sur la qualité des applications testées. Mais il ne faut pas confondre reporting et justification.

Certes, si seulement 30 % des tests de la campagne prévue ont été exécutés, l’équipe de test devra être en mesure d’expliquer pourquoi. Et les raisons peuvent être excellentes : sélection des tests joués en fonction de l’étude des impacts de l’évolution, optimisation du temps pour livrer dans les meilleurs délais, couverture complémentaire par des tests exploratoires…

Le reporting est un outil qui permet d’appuyer le discours de l’équipe de test. En outre, en aucun cas la nécessité de reporting ne doit empêcher l’équipe de test de procéder à des tests inédits, qui ne seront pas forcément formellement tracés. Tel cas de test écrit peut donner au testeur l’idée de dévier un peu et d’explorer un scénario de test différent, augmentant ainsi la couverture sans pour autant laisser de trace. Cette pratique de « hors-piste » permet d’ailleurs de mettre à l’épreuve les tests écrits. Un nouveau bug détecté ? On écrit un scénario pour compléter le patrimoine existant.

La liberté de tester est essentielle, et il serait contre-productif d’exiger un rapport exhaustif de tous les tests joués lors d’une campagne.

Répondre aux besoins plutôt qu’aux lubies

Une démarche d’élucidation du besoin, par exemple avec la technique des 5 pourquoi, est à mettre en œuvre pour comprendre la nécessité du reporting demandé. De quoi renforcer les liens avec les autres interlocuteurs, tout en se donnant l’occasion d’améliorer ses façons de faire.

Exemple d’échange fictif avec un Project Manager aussi zélé que nerveux :

QA : Pourquoi veux-tu un compte-rendu de tous les tests écrits et exécutés cette semaine ?

PM : Pour voir s’ils couvrent bien ce que j’imagine pour la User Story qui est en train d’être développée.

QA : Pourquoi as-tu des doutes là-dessus ?

PM : Parce que je ne sais absolument pas ce qu’il se passe en environnement de test, par exemple les jeux de données qui sont créés et comment ils sont utilisés.

QA : Pourquoi n’as-tu pas cette vision ?

PM : Je n’ai pas accès à cet environnement.

QA : Pourquoi ?

PM : J’ai fait une demande, mais les développeurs préfèrent ne pas m’y donner accès.

QA : Pourquoi ?

PM : Je pense qu’ils ont peur que je m’affole si je vois des bugs sur cet environnement par nature un peu instable. Du coup, je passe par vous. J’imagine que vous tracez tout ce que vous testez, c’est pour ça que je vous demande ces livrables plutôt que d’insister encore auprès des développeurs.

Dans cet exemple un peu caricatural, on voit que la vraie bonne réponse n’est pas de donner le compte-rendu exhaustif demandé, mais :

  • D’approfondir l’inquiétude quant à la User Story évoquée : on dirait que des éléments ne sont pas clairs pour tout le monde
  • D’engager un dialogue ouvert entre les développeurs et le Project Manager : dans quel objectif et sous quelles conditions ce dernier pourrait-il avoir accès à l’environnement de test ?
  • De clarifier auprès du Project Manager la façon dont sont organisés les tests, afin qu’il comprenne pourquoi (le cas échéant) tout n’est pas systématiquement tracé.
  • D’envisager un échange avec le Project Manager au sujet des jeux de données, il a vraisemblablement des éléments qui pourraient permettre de rendre les tests plus pertinents.

Prévenir plutôt que guérir

Tout ce que nous venons de décrire correspond tout de même à un scénario à éviter au maximum. L’idéal est bien sûr de pouvoir anticiper en réfléchissant dès le départ à des façons d’évaluer les tests et de communiquer sur la qualité des tests. Comme l’écrivent Janet Gregory et Lisa Crispin : « When our work is transparent for the organization, the need for control is reduced » (More Agile Testing, notre livre de chevet, qui n’a pas pris une ride depuis 2014).

Dès que possible, il sera intéressant d’analyser les éléments attendus pour que chacun puisse avancer sereinement :

  • Fréquence, teneur et présentation des rapports de tests
    • Si votre interlocuteur n’a pas d’idée précise en tête, présenter un rapport existant : faudrait-il imaginer quelque chose de plus fourni, plus clair, plus visuel, moins technique… ?
  • KPI (Key Performance Indicators) de l’équipe de test (comme promis, nous y reviendrons prochainement, car ça n’a rien de trivial)
  • Accès en lecture aux cas de test et/ou aux campagnes de test
  • Implication d’autres équipes dans les activités de test
  • Traçabilité plus forte entre les exigences, les cas de test et les anomalies
  • Ateliers et réunions

Les possibilités sont infinies et gagnent à être co-construites.

A chaque fois, comprendre l’objectif du livrable demandé, pour être sûr de ne pas faire fausse route (lubie versus besoin !) et pour savoir exactement quoi communiquer.

Et vous, en tant que testeur ou à l’inverse en tant qu’interlocuteur de testeurs, comment organisez-vous la communication sur la qualité des tests logiciels ?