Les 7 principes généraux du test en illustrations

Remerciements préalables

EDIT (paragraphe ajouté le 20 septembre 2018)

Ces illustrations ont été réalisées grâce au réjouissant projet open-source Historic Tale Construction Kit, version Bayeux. Merci à leurs concepteurs Leonard Allain-Launay, Mathieu Thoretton et Maria Cosmina Etegan !

Dans notre enthousiasme nous avions omis de les citer dans la première mouture de cet article, datée du 14 septembre 2018. Merci à l’un de nos lecteurs de nous avoir signalé cet impardonnable oubli !

Les tests montrent la présence de défauts

Et non leur absence. Comme le dit l’adage, l’absence de preuve n’est pas la preuve de l’absence…

Un testeur se faisant questionner par une équipe produit, et résistant à leur besoin d'entendre qu'il n'y a aucun bug dans l'application.

Les tests exhaustifs sont impossibles

D’où la nécessité d’une stratégie de test basée sur les risques et d’un ciblage pertinent de l’effort de test.

Un testeur tentant vainement d'atteindre les cimes de l'exhaustivité.

Tester tôt

Il est plus simple, plus rapide et plus économique de corriger une ambiguité dans une user story ou un cahier des charges, que d’improviser un patch après la découverte d’un bug majeur en pré-production. C’est en ça que le test représente, contrairement à l’idée reçue, un gain de temps pour les équipes. Reste à trouver un moyen de quantifier ce temps gagné pour convaincre les derniers sceptiques !

Il vaut mieux corriger un petit bug aujourd'hui qu'un gros bug demain.

Le regroupement des défauts

Après avoir éprouvé vos cas de test une première fois sur l’application, vous pourrez certainement identifier les fonctionnalités les plus « buggantes ». L’effort de test pourra alors être accru sur ces zones. Attention, les bugs peuvent changer de planque au fil du temps, ce qui nous amène au principe suivant…

Un testeur, cherchant en vain une colonie de bugs, qui se calfeutre à son insu dans une masure?

Le paradoxe du pesticide

De même que les insectes développent des résistances contre les pesticides, les cas de tests répétés à l’identique au fil du temps perdent de leur efficacité. Garder un référentiel de tests trop statique tend à laisser les bugs proliférer dans les friches. Il est essentiel de revisiter périodiquement sa combinatoire : le Docteur Lenoir ne se fait pas toujours tuer par le Colonel Moutarde avec un chandelier dans la véranda ! 

Testeurs cherchant en vain des bugs là où, à force d'être traqués, ils ne s'aventurent plus.

Les tests dépendent du contexte

Le contexte métier, le moment de l’année, le nombre et les caractéristiques des utilisateurs constatés au cours des derniers mois… sont autant d’éléments précieux qui permettent d’identifier les types de tests à prévoir.

Il ne faut pas tester la voile si le bateau est sur la plage.

L’illusion de l’absence d’erreur

Ce principe est certainement celui qui en dit le plus long sur le rôle du testeur. L’exigence de qualité nécessite de comprendre en profondeur le besoin des utilisateurs finaux, c’est pourquoi le testeur doit endosser un rôle proactif d’interface entre équipe technique et équipe métier. Sans cela, on aboutira à un produit bien fait, qui ne sera pourtant pas le bon produit.

Qui construit un arc parfait doit s'assurer que son client n'attend pas une harpe.

Bonne chance

… si vous passez prochainement votre examen ISTQB Foundation !

Vous pouvez librement utiliser ces images en citant Hightest et en indiquant un lien vers notre blog.

Vous reprendrez bien un peu d’humour testeur 🙂

Ce n’est pas un bug, c’est un poème

3 maladies de l’automatisation des tests

Le kit de secours métaphorique du testeur agile

Et un supplément de memes inédits ? C’est par ici !

… et d’ISTQB !

Performance, charge, stress… quelle différence ?

Gérer les paramètres Jenkins quand on est maniaque (ou flemmard)

Problème : des paramètres Jenkins interdépendants

Il n’est pas rare, quand on construit un build Jenkins avec des paramètres, que ceux-ci dépendent les uns des autres.

Exemple de configuration

Vous avez un paramètre de choix « Type de plat » avec comme valeurs possibles « Entrée », « Plat », « Dessert » et « Après-dessert » (un après-dessert est toujours le bienvenu).

Vous avez un autre paramètre de choix « Plat » avec comme valeurs possibles « Champignons à la grecque », « Spaghettis au roquefort », « Brownie » et « Salade de kiwis ».

Vous avez en tête un certain nombre de règles.

  • Les champignons à la grecque peuvent être commandés en tant qu’entrée ou plat principal
  • Les spaghettis au roquefort sont un plat
  • Il est possible de commander un brownie en dessert, mais pas en après-dessert, car ce ne serait pas raisonnable
  • La salade de kiwis peut être commandée en dessert ou en après-dessert.

Pourquoi cette configuration pose-t-elle problème ?

Possibilité 1 : vous êtes prudent (ou maniaque) et aimeriez interdire certaines combinaisons incohérentes.

Possibilité 2 : vous êtes flemmard et aimeriez gagner un peu de temps au moment de lancer un build.

Heureusement que la vie est bien faite et qu’il existe un plugin rien que pour vous.

Solution : Active Choices, un plugin Jenkins pour créer des conditions entre paramètres

Autrefois appelé Uno-Choice, le plugin Active Choice est gratuit et disponible directement depuis le gestionnaire de plugins de Jenkins.

Exemple d’utilisation d’Active Choices

Pour le cas énoncé, nous allons ajouter au job un paramètre de choix. Veillons simplement à ce que son nom soit en un seul mot, en écrivant « Type de plat » en camelcase. C’est important pour pouvoir ensuite utiliser ce nom comme une variable.

Maintenant, au lieu de créer un autre paramètre de choix classique, ajoutons un paramètre de type « Active Choices Reactive Parameter ».

Il faut maintenant cocher la case « Groovy Script », qui va nous permettre d’écrire nos règles. Ici, le script correspondant est le suivant :

if (TypeDePlat.equals("Entrée")) {
    return ["Champignons à la grecque"]
} else if (TypeDePlat.equals("Plat de résistance")) {
    return ["Champignons à la grecque", "Spaghettis au roquefort"]
} else if (TypeDePlat.equals("Dessert")) {
    return ["Brownie", "Salade de kiwis"]
} else if (TypeDePlat.equals("Après-dessert")) {
    return ["Salade de kiwis"]
} else {
    return ["Des petits cailloux ramassés dans l'allée"]
}

On indique une valeur par défaut dans le Fallback Script (par prudence, veiller à ce qu’elle soit cohérente avec la première valeur du paramètre de choix standard) :

return ["Champignons à la grecque"]

Maintenant, il faut simplement préciser à quel paramètre on se réfère.

Après sauvegarde de la configuration, lorsqu’on lance un build avec des paramètres, la liste déroulante des plats se met à jour en fonction de la valeur choisie dans la liste des types de plats. Pratique !

Ordre d’apparition des paramètres

Si vous êtes vraiment maniaque, vous remarquerez que les paramètres s’affichent dans la liste déroulante dans le même ordre que celui du script, et que par défaut, c’est le premier élément de la liste qui sera choisi.

Pour modifier cette valeur sans changer l’ordre alphabétique, au lieu de mettre l’élément voulu au début de la liste, il suffit de lui apposer « :selected« , comme ci-après :

return ["Champignons à la grecque", "Spaghettis au roquefort:selected"]

Conclusion

Le plugin offre de nombreux paramétrages possibles ; prenez le temps de les essayer, ça en vaut la peine !

Vous aimerez peut-être…

SonarQube met son grain de sel dans Gitlab !

Cas d’usage : JSoup et Gatling pour repérer les liens morts

L’automatisation des tests, c’est votre dada ? Voilà une ressource qui en parle en long, en large et en travers !

Ce n’est pas un bug, c’est un poème

Dear Evil Tester

Un bon testeur est un testeur diabolique ; c’est ce qu’Alan Richardson met en avant dans Dear Evil Tester, un recueil de questions-réponses issues d’une chronique au sein du journal The Testing Planet. Une lecture facétieuse, qui prend le contre-pied de tous les dogmes gravitant autour du test. Alan Richardson nous invite à bousculer nos certitudes et appelle à interroger constamment le métier de testeur.

Everyone can add mutation to the testing DNA.

Cerise sur le gâteau, il nous régale d’un poème, As if it were the first day. Comme il nous a plu, nous vous en proposons une traduction libre.

Comme au premier jour

Ce n’est pas le code que le testeur affronte,
C’est lui-même qu’il met au défi, en quête
Des manières dont on il aurait pu (la honte !)
Ignorer des trous dans la raquette.

Si on laisse le temps émousser notre regard
Les bugs nous échapperont par millions et par milliards.

Alors, méfiant, je reste sur mes gardes
J’ai peur qu’un autre me chaparde
Ce petit truc sans conséquence
« Comment ne l’ai-je pas vu, ça n’a pas de sens ! »

Il n’y a rien de tel que le passé : l’expérience du temps est une illusion
Il n’y a rien de tel que le présent, et j’ai la solution.

Je reste dans l’instant, mais pas dans le plan-plan
Je reste alerte, yeux grands ouverts et armé jusqu’aux dents
De mes talents, de mes modèles et mes outils (la fine équipe !)
L’appli ne peut pas gagner. C’est mon seul principe.

Je ne reteste pas. Je teste, je teste et je teste encore,
Comme au premier jour, aussi bien et aussi fort.

Bonne lecture, et n’hésitez pas à poster en commentaire ce que vous avez pensé de ce livre !

Vous pouvez même télécharger le poème au format image comme ci-dessous s’il vous prend l’envie de l’afficher dans votre bureau…

Une chanson sur le test logiciel ?

Ceci est une mise à jour du 27 mai 2019.

Dans le même registre, nous venons de découvrir sur le site Test Automation University une chanson sur la testeuse Angie Jones. Bonne écoute, et n’hésitez pas à nous faire part de toute autre œuvre lyrique sur notre beau métier !

Vous reprendrez bien un peu d’humour testeur 🙂

Les 7 principes généraux du test en illustrations

3 maladies de l’automatisation des tests

Le kit de secours métaphorique du testeur agile

Chiffres sur l’accessibilité du web calédonien

Infographie sur l’accessibilité des sites calédoniens

A partager sans modération ! L’article qui suit reprend et explique chacune des données découvertes, expose la méthodologie et ses limites, et donne un rappel sur la nature et le rôle de l’accessibilité numérique. Vous pouvez également télécharger l’infographie (image au format PDF de 446 Ko).

Pourquoi mesurer l’accessibilité ?

L’accessibilité est un sujet encore insuffisamment maîtrisé, en métropole comme en Nouvelle-Calédonie. C’est un état de fait que l’on peut constater en navigant sur un certain nombre de sites web. Nous avons mené cette étude pour pouvoir préciser ce constat par des chiffres.

Quels critères d’accessibilité ont été analysés ?

Le choix d’un standard international

Des règles pour l’accessibilité des contenus web existent et forment un standard : le WCAG (Web Content Accessibility Guidelines). Pour chaque thématique, des règles sont proposées par niveau d’accessibilité souhaité (A, AA ou AAA).

Une partie de ces recommandations peut être vérifiée par un simple script de test automatique. Parmi celles-ci, nous avons retenu :

  • Présence d’un attribut de texte alternatif sur toutes les images (règle 1.1.1, niveau A)
  • Unicité du texte alternatif des images par rapport au contenu lisible et par rapport aux autres textes alternatifs de la page web (règle 1.1.1, niveau A)
  • Lisibilité du texte alternatif (celui-ci ne doit pas être le nom de fichier de l’image) (règle 1.1.1, niveau A)
  • Unicité des textes des liens pointant vers des ressources différentes sur une même page web (règle 2.4.4, niveau A)
  • Présence d’un attribut indiquant la langue de la page (règle 3.1.1, niveau A)

Partant de ce constat, nous avons décidé d’étudier ces critères sur un large corpus de sites web calédoniens. Nous avons utilisé l’outil de scrapping JSoup, dont nous vous avons parlé dernièrement.

Parallèlement à l’analyse de ces critères, nous avons aussi étudié l’utilisation (quantitative) de la famille d’attributs « aria » et de l’attribut « tabindex« . Ces attributs ont vocation à améliorer l’accessibilité et l’ergonomie des sites web. Cependant, ces attributs sont parfois inclus par défaut dans les templates de sites et ne sont donc pas forcément sciemment implémentés par l’entité responsable d’un site. D’autre part, ces attributs peuvent faire l’objet d’une utilisation erronée ; leur présence au sein d’une page web ne veut pas forcément dire qu’elle est plus accessible qu’une autre.

Limites de l’analyse

  • Les informations récoltées sont des indicateurs isolés qui ne sondent que grossièrement le niveau d’accessibilité des sites.
  • Certains sites web calédoniens n’ont pas d’extension en « .nc » et n’ont pas été inclus dans l’analyse.
  • Pour certains critères, certains sites n’ont pas pu être étudiés suite à des indisponibilités ou des incompatibilités techniques. Dans le pire des cas, 33 sites sur 800 n’ont pas pu être analysés.

Quels chiffres pour l’accessibilité calédonienne ?

Corpus

Le corpus est composé de la page d’accueil de 800 sites web calédoniens. Les sites les plus connus (sites institutionnels, administrations, médias…) y côtoient des sites commerciaux et associatifs. Les sites personnels de particuliers ne sont pas représentés.

La langue des pages est-elle déclarée ?

  • 25 % des pages ne déclarent pas la langue du document. Une mesure pourtant peu coûteuse, puisqu’il s’agit d’un simple attribut à ajouter dans la balise html. La langue du document est une donnée utile pour les logiciels lecteurs d’écran, mais peut aussi être utile pour le référencement. En savoir plus sur l’attribut « lang »
  • 7 % des pages où la langue est déclarée indiquent une langue qui n’est pas pertinente ; majoritairement l’anglais, mais aussi le portugais et le « nc », qui n’est pas une langue ! Ces mauvaises pistes représentent 5 % du corpus total.

Les images sont-elles accessibles ?

Données générales sur les images

  • 90 % des pages d’accueil contiennent au moins une image déclarée dans le DOM (et non chargée par CSS).
  • 14 images : c’est le nombre médian par page d’accueil. Le nombre moyen est 24 et le nombre maximum, 1473.
  • 47 % des attributs de texte alternatif sont vides (notés alt= » ou alt). Cela n’est pas un problème en soi ; cela signifie simplement que les synthèses vocales passeront sur les images sans donner d’information. Cette pratique est particulièrement pertinente pour les images à seul but décoratif.

Données sur l’accessibilité des images

  • 20 % des images n’ont pas d’attribut de texte alternatif (même vide). Les synthèses vocales sont susceptibles de passer dessus en disant « image », ce qui n’apporte aucune valeur à l’utilisateur, et peut être irritant si le site contient beaucoup d’images. Si l’image contient des informations nécessaires à la compréhension du contenu, l’utilisateur en sera privé si sa machine ne charge pas les images, ou s’il est aveugle.
  • 11 % des pages n’ont d’attribut de texte alternatif sur aucune de leurs images. 33 % en ont un pour chaque image.
  • 34 % des textes alternatifs non vides contiennent du texte qui se trouve déjà dans le texte visible de la page. Cette utilisation n’est pas toujours erronée ; un logo dans le header avec comme texte alternatif « Accueil » est acceptable. Toutefois, une analyse plus poussée des données récoltées a montré que bien souvent, ces textes alternatifs étaient effectivement redondants.
  • 18 % des textes alternatifs non vides possèdent au moins un doublon (image sur la même page ayant le même texte alternatif). Sur la page d’accueil d’un site de billetterie en ligne, il y a 40 doublons de ce type !
  • 2 % des textes alternatifs sont des noms de fichier (par exemple : photo00032.jpg).

Accessibilité des liens

Données générales sur les liens

  • Lors d’une navigation au clavier et au lecteur d’écran, le texte des liens prend toute son importance, car chaque lien est susceptible d’être lu hors de son contexte. Il est donc important de choisir de textes parlants, comme « notre point de vue sur le World Quality Report de 2017-2018« , plutôt que des textes génériques comme « dans cet article » ou « cliquez ici ».
  • 14 liens : c’est le nombre médian par page d’accueil. Le nombre moyen est 26 et le nombre maximum, 1215.

Données sur l’accessibilité des lien

  • 5 % des liens partagent leur texte avec un autre lien de la même page dont la destination est différente. Problème : comment faire la différence entre 2 liens qui se suivent et indiquent « En savoir plus » ? Sur une des pages étudiées (la page d’accueil du site d’une agence immobilière), 55 liens sont dans ce cas de figure.
  • Pour 30 % des liens, c’est l’inverse (ils pointent vers la même ressource mais ont un texte différent), ce qui est beaucoup moins problématique. Par exemple, on imagine bien qu’un lien « La dernière version » puisse pointer vers la même ressource qu’un lien « La version de juin 2018 ».

Présence d’attributs aria et tabindex

  • 16 % des pages comptent au moins un attribut aria-*
  • 10 % des pages comptent au moins un attribut tabindex

Rappel : quels sont les enjeux de l’accessibilité ?

Améliorer l’expérience de l’ensemble des utilisateurs

Accessibilité et handicaps sont souvent associés. Mais contrairement à l’idée répandue, l’accessibilité n’est pas une affaire de personnes handicapées, mais plutôt de situations de handicap, car tout un chacun peut être amené, temporairement ou situationnellement, à être privé de tout ou partie de l’acuité d’un de ses sens. Quelques exemples :

  • La difficulté à lire l’écran de son smartphone quand on le consulte en plein soleil
  • La photophobie provoquée par une forte migraine
  • La difficulté à écouter une émission quand on se trouve dans un bus bondé en centre-ville

Le matériel que l’on utilise peut lui-même nous mettre en situation de handicap :

  • Ecouteurs en panne
  • Ecran anormalement terne
  • Connexion internet bas-débit

Le kit de design inclusif de Microsoft illustre par exemple cette diversité de contextes en montrant qu’on peut avoir « un bras en moins » lorsqu’on est amputé, plâtré, ou simplement occupé à tenir un bébé.

Les bonnes pratiques d’accessibilité sont donc profitables à tous et permettent de construire du contenu tout-terrain. Ce faisant, on améliore les conditions de la satisfaction utilisateur et le rendement de ses services en ligne.

Résorber les fractures numériques

Ceci étant dit, il est correct de dire qu’une part grandissante de la population se trouve dépendante de l’accessibilité des services web.

Selon l’enquête HID, il existait en France 1,7 millions de déficients visuels en 1999, dont plus de 200 000 aveugles ou malvoyants profonds. A l’époque, cela représentait 2,9% de la population. Un nombre similaire (2,8%) a été obtenu en 2012 au Canada. Ajoutez à cela le fait que le nombre de déficients visuels est en forte augmentation dans le monde entier dû au vieillissement de la population.

Nombreux sont les éléments à prendre en compte pour aller vers plus d’accessibilité : malvoyance, malentendance, cécité, surdité, daltonisme, épilepsie, dyslexie…

Plus le temps passe et plus la société se digitalise ; il n’est donc pas question de laisser de côté une si grande partie de la population.

L’accessibilité : une obligation juridique

Soulignons que depuis 2005, l’accessibilité des sites web est en France un enjeu juridique. Depuis la loi pour l’égalité des droits et des chances, la participation et la citoyenneté des personnes handicapées, il est obligatoire aux sites institutionnels de fournir des services en ligne accessibles. En octobre 2016, la Loi pour une République numérique a rappelé cette obligation.

Mais les associations considèrent souvent que cette législation est insuffisante et trop peu appliquée. A l’heure actuelle, l’accessibilité est encore majoritairement le fruit de décisions volontaires, plutôt que celui d’une obligation légale. Une raison de plus de prendre conscience de sa responsabilité individuelle dans ce domaine.

Sur notre blog, vous pourrez découvrir d’autres articles sur ce thème. L’an dernier, nous avons participé à un défi du Ministry of Testing sur l’accessibilité, et il y a deux mois nous avons rencontré Marie-Françoise Pierre, une entrepreneuse malvoyante.

Durant cette analyse, nous avons découvert un certain nombre de freins à l’accessibilité sur notre site, et nous sommes en train de les résoudre. Et vous, que pourriez-vous améliorer ? Histoire de ne pas être dans nos prochaines statistiques… Sourire

Autres articles sur le thème de l’accessibilité

Malvoyance – vis ma vie numérique avec Marie-Françoise Pierre

30 days of accessibility testing

 

Wikipedia, nous voilà !

Qu’est-ce qu’un testeur ?

Il y a plusieurs sortes de testeurs : il y a les flacons de parfum qui ne seront pas vendus, les consommateurs rémunérés pour évaluer des produits alimentaires, et aussi les équipements électroniques qui mesurent le Ph d’une piscine. Des questions ?

Nous sommes testeurs et, lorsqu’on nous demande notre métier, il nous faut souvent broder un peu pour que notre interlocuteur non-informaticien comprenne de quoi il s’agit. Et l’article Wikipedia sur les testeurs ne nous aide pas beaucoup…

« Un testeur, en informatique, est une personne chargée de tester le logiciel produit par les programmeurs, et de livrer à intervalles réguliers un rapport décrivant les erreurs trouvées dans le produit. »

Si tous les testeurs qui ne correspondent pas vraiment à cette définition se tenaient par la main, la chaîne humaine serait au moins aussi longue que la distance qui nous sépare de la métropole (à hauteur de 100 000 personnes mesurant en moyenne 1 mètre 70 d’envergure, on est peut-être même en-deçà de la vérité).

Mais continuons de nous promener sur l’encyclopédie en ligne.

Qu’est-ce que l’automatisation des tests ?

L’automatisation des tests et l’une de nos activités à forte valeur ajoutée ; qu’en dit Wikipedia ?

L’article sur l’automatisation des tests, à l’état d’ébauche, compte dix lignes et pas une de plus. Dont cette phrase malheureuse :

« Plusieurs éditeurs proposent à ce jour des robots de tests, par exemple Smartbear (outil : TestComplete), Selenium ou la société Applause. »

Aïe, depuis quand Selenium est une société ? Depuis quand Smartbear n’a qu’un seul outil ? Et… pourquoi Applause ? Dans l’historique, on voit que le contributeur a simplement rajouté cette mention par esprit d’équité :

« Il est peu objectif de ne proposer que 2 logiciels. J’ai rajouté un prestataire différent, proposant une méthodologie autre que le software. Il est leader mondial, il me semble donc normal que son nom soit cité. »

« Une méthodologie autre que le software » : si un jour vous écrivez un livre, essayez de ne pas l’appeler comme ça… Mais ne jetons pas la pierre à ce contributeur ; sur Wikipedia, les uns corrigent les erreurs des autres, et son approximation aurait dû être épongée depuis des mois (par vous et par nous).

Allez, on se donne une troisième chance ?

Qu’est-ce que… non, rien.

Si on parlait de test agile ? Mince, l’article n’existe pas. De test d’accessibilité ? Non plus. Gestion des anomalies, gestion des tests, rien, nothing, nada.

Et en anglais ? Là c’est moins pire. Les thématiques principales du test logiciel sont abordées, il y a un peu plus de pages, avec un peu plus de contenu. Mais tout ça laisse sur sa faim. Car sur d’autres pans de Wikipedia, lorsqu’un article en langue X est de bonne qualité, un article en langue Y s’en inspire et indique clairement qu’il s’agit d’une reprise ou d’une traduction.

De plus, il serait inexact de dire que ce triste sort est réservé à tous les « nouveaux métiers » (d’ailleurs, le test logiciel n’est pas un domaine métier si récent). Des pages plus fournies existent sur les responsables du bonheur (chief happiness officers), les animateurs de communautés (community managers), sur l’optimisation des moteurs de recherche (ou SEO) ou encore sur le devOps.

Qu’en conclure ? Google régurgitera-t-il impassiblement, année après année, cette soupe froide et indigeste dès que le moindre curieux s’enquerra de notre passionnant métier ? Les pépites sont-elles vouées à rester cachées dans les livres ? Une encyclopédie vivante du test logiciel est-elle impossible ?

A grand pouvoir, grande responsabilité

Vous vous en doutez, on ne peut pas conclure là-dessus. Car à quoi bon continuer de se lamenter sur cette piteuse vitrine, quand nous sommes à même d’être le changement que nous voulons voir… Allez, on s’y met ?

Si le coeur vous en dit, indiquez votre pseudo Wikipedia en commentaire, nous serons heureux d’aller lire votre travail !

Cas d’usage : JSoup et Gatling pour repérer les liens morts

Attention, le contenu de cet article a été rédigé il y a de nombreuses années ! Il est possible que les bouts de code écrits à l’époque ne fonctionnent plus sur les nouvelles versions des outils mentionnés. Si vous souhaitez découvrir nos articles les plus récents, nous vous invitons à rejoindre la page d’accueil de notre blog !

Comment maintenir la qualité d’un blog ?

Les liens morts : un des aléas du web

Quelle satisfaction de voir qu’au bout de plusieurs mois, un article de blog est encore souvent visité et bien référencé. Mais il ne faut pas se reposer sur ses lauriers, car malgré ces bons résultats, il se peut qu’il ne soit plus ce qu’il était.

Il y a un mois, nous avions le nom d’un outil d’accessibilité sur le bout de la langue, nous nous sommes rendus sur le blog Hightest car on en avait parlé précédemment. Et là, on tombe par hasard sur un lien mort. Une question s’impose : combien y en a-t-il en tout sur le blog et quelle solution mettre en place contre ce problème ?

Dénombrer les liens morts en quelques clics

Nous avons d’abord procédé à un état des lieux avec le Link Checker du W3C. C’est un peu fastidieux, l’outil vérifie absolument tous les liens (même les liens vers les fichiers css et js, qui ne nous importent pas dans ce contexte), et on se retrouve sous une marée d’informations. On y a passé un peu plus de temps qu’on l’aurait voulu.

Le verdict ? Sur 162 liens externes, le Link Checker a trouvé 7 liens morts répartis sur 30 articles. En plus de ces 7 liens, beaucoup de faux positifs, en particulier lorsqu’il vérifie la disponibilité de documents PDF en ligne, sans compter les liens d’exemple fournis dans le corps des articles (ex : http://votresuperdepot.git). En effet, notre moteur de blog crée automatiquement des liens sur les chaînes commençant par « http:// ».

Pas mal de redirections aussi, qui sont moins graves que des liens morts mais qui nécessitent aussi de mettre à jour les liens, ne serait-ce que pour faire gagner un peu de temps de chargement à l’utilisateur.

Les liens morts ont été remplacés ou supprimés dans la foulée.

Trouvailles et avantages collatéraux

En plus du diagnostic des liens morts et redirigés, le check nous a permis de :

  • constater un nouveau bug sur notre blog, corrigé dans la foulée par notre webmaster
  • découvrir un problème sur le forum de Katalon (disparition de commentaires de membres de l’équipe Katalon), signalé dans la foulée aux administrateurs
  • relire certains passages et consolider le souvenir de certains points un peu oubliés au fil des mois.

L’exercice en valait donc la peine.

Automatiser la vérification des liens morts

A quelle fréquence devrions-nous vérifier que les liens sont toujours valides ? Tous les ans, c’est trop peu. Tous les jours, cela prendrait trop de temps… à moins que nous l’automatisions.

Nous avons donc mis en place un petit check automatisé à l’aide de JSoup, Gatling et Jenkins.

Vue d’ensemble de la solution

Voici comment ça se passe :

  • Jenkins lance le test tous les jours à minuit.
  • Juste avant le test, le parseur JSoup récupère tous les liens présents dans les articles du blog et les stocke dans un fichier. Les liens internes sont ignorés, ce qui enlève du bruit par rapport au Link Checker du W3C. Une liste de « faux liens morts » est également ignorée, qui contient les liens type localhost etc.
  • Puis, un test Gatling accède à chacun des documents vers lequels pointent les liens et vérifie les codes de statut de réponse HTTP.
  • Si, parmi tous les liens, il existe au moins un code différent de 200 (qui signifie que la requête s’est effectuée de manière nominale), le test est en erreur. Un mail est envoyé à l’équipe pour analyse.

Le script Gatling

Ce script récupère lit fichier CSV (ici, « urls_in_blog_hightest.csv ») pour récupérer l’adresse des liens cités. Il vérifie que chacun des liens pointe vers une ressource disponible.

Le fichier CSV ressemble à cela :

Article Lien
https://www.hightest.nc/blog/posts/urldelarticle1 http://www.unsite.nc
https://www.hightest.nc/blog/posts/urldelarticle1 http://www.unautresite.nc/superarticle
https://www.hightest.nc/blog/posts/urldelarticle2 http://www.encoreunautresite.nc/merveilleuseinfographie

 

Et le script Gatling est le suivant :

package simulations

import io.gatling.core.Predef._
import io.gatling.core.feeder.RecordSeqFeederBuilder
import io.gatling.core.structure.{ChainBuilder, ScenarioBuilder}
import io.gatling.http.Predef.{http, status}
import io.gatling.http.protocol.HttpProtocolBuilder

class CheckForDeadLinks_BlogHightest extends Simulation {

  val successStatus: Int = 200
  val httpProtocol: HttpProtocolBuilder = http
    .check(status.is(successStatus))
  
  val liensBlog: RecordSeqFeederBuilder[String] = csv("src/test/resources/jeux_de_donnees/urls_in_blog_hightest.csv")

  def checkUrlOK(url: String): ChainBuilder = exec(
    http("check_url_" + url)
      .get(url))
  
  val scnVerificationLiensBlog: ScenarioBuilder = scenario("Vérification des liens présents sur le blog Hightest")
    .repeat(liensBlog.records.size) {
      feed(liensBlog)
        .exec(checkUrlOK("${Lien}")) // C'est ici que Gatling utilise la valeur du fichier CSV
    }

  setUp(scnVerificationLiensBlog.inject(constantUsersPerSec(1) during 1).protocols(httpProtocol)).assertions(
    global.successfulRequests.percent.is(100)
  )
}

Récupération des liens et alimentation du fichier CSV

Le fichier CSV montré précédemment est alimenté par JSoup. Pour chacun des liens présents dans le blog, cette méthode est appelée et retourne la liste des liens présents dans la page conformément au format du fichier (« article, lien trouvé ») :

private ArrayList<String> recupererLiensArticle(String site, String article){
    ArrayList<String> urlsDansLarticle = new ArrayList<>();
    try {
        Document dom = Jsoup.parse(new URL(article).openStream(), "UTF-8", article);
        Elements liens = dom.getElementsByTag("a");
        for (Element lien : liens) {
            String destinationLien = lien.attr("href");
            if (!urlsDansLarticle.contains(article + "," + destinationLien)
                    && !urlsDansLarticle.contains(article + "," + site + destinationLien)) {
                if(destinationLien.contains("http")){
                    urlsDansLarticle.add(article + "," + destinationLien); // liens absolus
                } else {
                    urlsDansLarticle.add(article + "," + site + destinationLien); // liens relatifs
                }
            }
        }
    } catch (IOException e) {
        System.out.println(article + " : " + e);
    }
    return urlsDansLarticle;
}

Résultat : chacune des destination des liens est stockée, les doublons sur la page sont gérés. Nous conseillons de gérer aussi les doublons globalement, pour éviter de charger plusieurs fois une même ressource citée dans différents articles.

Mission accomplie !

Après un mois de checks quotidiens, nous n’avons pas détecté de nouveaux liens morts, seulement un faux positif, un des sites mentionnés étant temporairement indisponible. Mais nous avons gagné en confiance et savons que nous serons probablement les premiers à être au courant si un de nos liens « meurt ».

MAJ de 2023 : ayant changé de stack, nous n’utilisons plus la solution présentée dans cet article. Il est possible que quelques liens morts soient apparus au fil du temps sur le blog… Nos excuses pour cela !

Vous aimerez peut-être…

Gérer les paramètres Jenkins quand on est maniaque (ou flemmard)

SonarQube met son grain de sel dans Gitlab !

Malvoyance – vis ma vie numérique avec Marie-Françoise Pierre

Une autre vision du web

Portrait d’un regard

Entrepreneuse, mère de famille et engagée dans diverses associations calédoniennes, Marie-Françoise Pierre passe une grande partie de ses journées devant des écrans. Nous l’avons rencontrée pour nous immerger dans sa vie numérique, qui est adaptée à son handicap : la malvoyance.

Dans cet article, nous allons présenter une vie numérique parmi des millions d’autres, en espérant qu’elle vous aidera à imaginer des sites plus accessibles, mais aussi détecter des problèmes d’accessibilité et en parler pour qu’ils soient corrigés.

Comment voit Marie ?

La déficience oculaire de Marie touche la partie centrale de sa rétine, la macula, ce qui affecte le centre de sa vision. Sa vision périphérique, en revanche, lui permet de se situer dans l’espace et de se déplacer sans problème. Cette déficience l’handicape à 80% ; certaines actions ne lui sont pas possibles, par exemple la conduite.

D’autres types de malvoyances impactent uniquement la vision périphérique, ce qui permet aux personnes de pratiquer des activités demandant une acuité visuelle fine, mais peut représenter un risque important lorsque des dangers surviennent sur les côtés.

Pour Marie, avoir une bonne hygiène de vie est impératif pour voir le mieux possible : une fatigue ou un manque de sommeil peuvent lui rendre encore plus difficile la lecture, voire lui occasionner des vertiges.

Si vous souhaitez expérimenter par vous-mêmes la façon dont Marie voit le monde, vous pouvez télécharger l’application Eye-View (disponible sur iOs et Android) et essayer la vue « DMLA » en agrandissant au maximum la tache grise centrale. Gardez bien votre regard au centre de la tache et laissez votre vision périphérique faire le reste… Pas facile !

Des équipements matériels et logiciels pour plus d’accessibilité

Chez Marie, tout est Mac : ordinateur, tablette et smartphone, car tous ces matériels intègrent directement des fonctions d’accessibilité pour les déficients visuels. Sinon sur PC, Marie doit être équipée du logiciel ZoomText, un logiciel qui coûte cher acheté individuellement (environ 60 000 francs pacifiques). Ces outils permettent de régler la taille du texte, la teinte et le contraste des couleurs, l’apparence du curseur, et propose également une synthèse vocale. Mais le plus souvent, Marie préfère ne pas utiliser la synthèse vocale ; elle a remarqué que celle-ci a tendance à s’entrecouper, répéter plusieurs fois la même chose, ou encore énoncer un autre texte que celui souhaité. Elle préfère lire elle-même les textes, aussi bien dans les visionneuses de documents que dans son client mail ou son navigateur.

Elle maîtrise Siri et a formé d’autres personnes dans le cadre l’association Valentin Hauÿ de Nouméa, mais a l’habitude d’écrire ses mails et autres messages au clavier.

Marie lit avec fluidité à condition que le texte soit à une taille suffisante (police 72 pour un document word affiché à 100%). Il est préférable aussi que la police soit sobre, sans empattements (lire cet article pour comprendre pourquoi !). Pour lire un texte, elle zoome au maximum, fait défiler la page horizontalement avec la souris, dézoome, rezoome… Toute une gymnastique qu’elle fait maintenant sans y penser. Elle explique qu’au départ ça donne un peu envie de vomir, mais qu’on s’y habitue vite.

Le clavier de Marie est tout à fait classique. Pour écrire avec plus d’aisance, elle y a simplement collé deux petits reliefs en plastique qui lui permettent de placer ses mains au bon endroit.

Elle utilise souvent l’appareil photo de son téléphone pour zoomer certains textes rencontrés dans la vie de tous les jours, par exemple des plaques portant un nom de rue, ou les cahiers d’école de ses enfants.

Des bugs auxquels vous n’auriez peut-être jamais pensé

Vous souhaitez construire des logiciels (plus) accessibles ? Voici maintenant des points soulevés par Marie au cours de sa vie d’internaute. Peut-être repenserez-vous à ces cas d’utilisation lors de votre prochaine phase de spécifications… Car une fonctionnalité qui semble parfaite pour une personne valide peut être perçue comme buggée (ou « buggante ») lorsque l’on navigue différemment.

Le menu glissant

Imaginez un site web avec un bandeau comprenant différents onglets thématiques. Lorsque vous survolez un onglet avec la souris, un menu apparaît. Et lorsque vous survolez un item de ce menu, un sous-menu apparaît. Et lorsque la souris quitte soit l’onglet, soit le menu, soit le sous-menu… Tout se replie.

Ce type de design est très courant, en particulier sur les sites de vente ; à peu près gérable quand l’écran est affiché à 100%, il devient cauchemardesque s’il est zoomé à 500%. Comment garder la souris sur ces éléments tout en faisant défiler l’écran horizontalement ? Ces menus interactifs peuvent devenir un casse-tête.

Le carrousel vertigineux

Certains carrousels d’images défilent automatiquement et nécessitent que l’on identifie rapidement les informations utiles et qu’on les lise dans la foulée. Or, pour Marie, l’étape d’identification est plus longue que prévu ; ce qui était censé être une animation agréable et vivante devient une chasse agaçante où l’on joue au chat et à la souris.

Le captcha indéchiffrable

Les captchas sont des outils plus ou moins efficaces pour limiter l’accès des robots sur certaines parties du web. Mais ils ne sont pas toujours accessibles : les lettres indéchiffrables et les contrastes insuffisants bloquent parfois à Marie l’accès à certains services.

Le curseur fugitif

Dans certaines applications, Marie a remarqué que lorsqu’on zoome au maximum un champ où l’on est en train de saisir du texte, le focus de l’écran ne suit pas automatiquement le curseur. Du coup, lorsque le curseur quitte l’écran, on ne voit plus ce qu’on écrit. Elle a remarqué ce comportement en particulier sur son client de messagerie.

La barre qui s’incruste

Quand Marie regarde une vidéo, elle n’a pas le temps de lire les sous-titres. Mais lorsqu’elle a besoin de les lire et qu’elle appuie sur « Pause », il arrive que la barre de lecture cache la partie basse de la vidéo, ce qui masque le texte.

Cette petite série de bugs n’est qu’un échantillon des embûches que l’on peut rencontrer lorsqu’on navigue autrement que ce qui était imaginé par le concepteur d’un site web. La prochaine fois que vous ouvrirez un site (probablement dans moins de quelques minutes), regardez-le avec un oeil différent ; quelles parties vous semblent bien pensées pour l’accessibilité ? Quelles parties laissent à désirer ? Adopter ce regard nécessite de l’entraînement, et des méthodes et outils peuvent vous aider à le faire, comme nous en parlions précédemment.

L’accessibilité, ce n’est pas que pour les autres

Au cours de sa vie professionnelle, Marie a remarqué que les logiciels destinés à un usage interne étaient souvent moins soignés en termes d’ergonomie et d’accessibilité que les logiciels ouverts à un public plus large. Un constat qui laisse pensif, à l’heure où l’insertion des personnes handicapées devrait être un enjeu important des entreprises.

Pourtant, au bureau ou ailleurs, la majorité des mesures d’accessibilité sont profitables autant aux personnes handicapées qu’aux autres. N’importe qui pourrait avoir besoin de capter toutes les infos d’un site sans se baser sur les images (sa connexion étant trop lente pour les charger par exemple), et donc de se servir des attributs de texte alternatif. N’importe qui, souffrant d’une migraine passagère ou de fatigue oculaire, pourrait apprécier un site dont les contrastes respectent les normes d’accessibilité.

Cela est vrai aussi « dans la vraie vie »… Vous le savez s’il vous arrive de préférer monter via la pente douce plutôt que par les escaliers.

N’hésitez pas à partager dans les commentaires votre expérience du handicap, de l’accessibilité et des bugs associés que vous avez rencontrés !

Autres articles sur le thème de l’accessibilité

Chiffres sur l’accessibilité du web calédonien

30 days of accessibility testing

Logs Selenium : passez au niveau big boss

Des logs Selenium lisibles pour tous

Nous parlions de ce syndrome dans un précédent article ; le testeur chargé de l’automatisation des tests est parfois le seul à comprendre ses logs (on a appelé ça la logopathie). Cela réduit l’utilité des automates qui se retrouvent auréolés d’un mystère inutile.

Pour poursuivre dans cette série de bonnes pratiques d’automatisation des tests, nous vous proposons aujourd’hui plusieurs approches pour améliorer vos logs Selenium, sans le moindre framework hipster, juste avec du bon vieux Java. Nous utiliserons un système de logging des plus classiques, à savoir Log4J2, réglé sur la verbosité « INFO ». Libre à vous ensuite d’exploiter ces logs dans l’outil de reporting de votre choix (Allure par exemple). Allez, c’est parti !

Le script Selenium niveau débutant : rien que les logs d’erreur par défaut

Exemple de script Selenium

Voici un script très optimiste qui vérifie sur un célèbre site de vente calédonien que la première Peugeot 107 à vendre coûte 10 000 francs pacifiques ou moins.

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class TestLogs {

    WebDriver driver;

    @Before
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "webdrivers/chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }

    @Test
    public void testLogs(){
    driver.get("https://voitures.nc/");
        WebElement element = driver.findElement(By.id("recherche"));
        element.sendKeys(Keys.DELETE);
        element.sendKeys("107");
        driver.findElement(By.cssSelector("input[value='OK']")).click();
        driver.findElement(By.xpath("//a[contains(., 'Offre')]")).click();
        driver.findElement(By.xpath("(//table[contains(@href, 'detail_annonce')]//img)[1]")).click();
        Assert.assertTrue("ERREUR : le prix affiché est supérieur à " + 10000, Integer.parseInt(driver.findElement(By.xpath("//div[contains(@id, 'detail')]")).getText(). split("Prix : ")[1].split(" F cfp")[0]. replaceAll("\s+", "")) < 10000);
    }

    @After
    public void tearDown(){
        driver.quit();
    }
}

Problèmes du script Selenium

Comment on va maintenir ça ?

Ce qui saute déjà aux yeux avec ce script, c’est qu’il enfreint la règle de séparation du test et des objets pages. Si le Page Object Model ne vous éveille aucun souvenir, allez jeter un œil à cet article.

Ecrivez tous vos tests de cette façon et vous obtiendrez un magnifique plat de spaghettis impossible à maintenir !

Mais ce qui nous dérange le plus ici, c’est qu’en cas d’échec, on n’aura pas beaucoup d’informations

Exemples de logs cryptiques

Si la première Peugeot 107 affichée coûte plus de 10 000 XPF, on se retrouvera avec ces logs :

java.lang.AssertionError: ERREUR : le prix affiché est supérieur à 10000

at org.junit.Assert.fail(Assert.java:88)
 at org.junit.Assert.assertTrue(Assert.java:41)
 at TestLogs.testLogs(TestLogs.java:33)
 // [...] Et encore plein de lignes qu'on vous épargnera

Et rien avant ce problème d’AssertionError. Là, on a bien le test en tête, on comprend ce qui s’est passé. Cela dit, dans 6 mois, on ne saura plus ce qui était censé coûter 10 000 XPF maximum, sur quel site, etc…

Et si jamais le bouton de recherche n’est pas trouvé, les logs remontent cela, ce qui est moins parlant :

*** Element info: {Using=id, value=recherche}

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
// [...]

Heureusement que le champ de recherche a un id et que celui-ci est explicite, mais ce n’est pas toujours le cas… Par exemple, sur le site d’Amazon, le champ de recherche a pour id « twotabsearchtextbox », ce qui est un peu moins compréhensible.

Le script Selenium niveau supérieur : chaque étape est logguée

Dans le bloc ci-dessous, le test a bien changé, il répond maintenant au pattern du Page Object Model. Il est beaucoup plus court, et surtout il est plus lisible grâce à des noms de méthodes explicites. Son setup et son teardown sont remontés d’un cran et se trouvent dans une nouvelle classe, « AbstractTest », dont hérite le test ; de cette façon, ils pourront être utilisés dans tous les tests.

La page invoquée, VoituresNcPage, a également son propre objet, qui contient ses propres méthodes.

Et les méthodes de bas niveau utilisées dans l’objet VoituresNcPage sont elles-mêmes remontées dans une classe mère, AbstractPage.

De cette façon, on respecte les célébrissimes principes DRY (don’t repeat yourself) et KISS (keep it super simple).

Le nouveau test Selenium

import org.junit.Test;
import pages.VoituresNcPage;
import utils.AbstractTest;

public class TestLogs extends AbstractTest {

    @Test
    public void testLogs() {
        accesURL("https://voitures.nc/");
        VoituresNcPage voituresNCpage = new VoituresNcPage(this);
        voituresNCpage.rechercherProduit("107");
        voituresNCpage.accesAuxOffres();
        voituresNCpage.classerParPrix();
        voituresNCpage.deplierAnnonceNumero(1);
        voituresNCpage.verifierPrixInferieurOuEgalA(10000);
    }

}

Les méthodes de haut et de bas niveau

Toutes les méthodes de bas niveau donnent lieu à une ligne de log. Les méthodes de vérification donnent lieu à un log en cas d’échec. Un exemple avec la méthode qui permet de classer les produits par prix :

// Dans VoituresNcPage. On trouve les objets et les méthodes spécifiques à la page.

private final By BTN_CLASSER_PAR_PRIX = By.xpath("(//a[contains(@href, 'orderBy=prix')])[1]");
public void classerParPrix(){
   clickElement(BTN_CLASSER_PAR_PRIX);
}

[...]
// Dans AbstractPage. On trouve des méthodes qui pourraient servir à toutes les pages web du monde. Des vérifications sont faites avant chaque interaction, pour vérifier que l'élément concerné est bien présent, et logger ce problème le cas échéant.

protected int timeOut = 5; // Cette valeur sert à configurer combien de temps un élément doit être "attendu" avant qu'on ne considère qu'il est absent de la page.

protected void clickElement(By by) {
 logger.info("Clic sur l'élément '" + getPathFromBy(by) + "'"); // Un premier log de bas niveau
 assertElementPresent(by);
 driver.findElement(by).click();
}

protected String getPathFromBy(By by){
    return by.toString().split(": ")[1]; // On a choisi de faire ce split pour gagner en concision, mais vous aurez peut-être envie de conserver le type de sélecteur.
}

public void assertElementPresent(By by) {
    if(!isElementPresent(by)){
        logger.error("ERREUR : '" + getPathFromBy(by) + "' n'a pas été trouvé(e) sur la page."); // Un deuxième log de bas niveau
    }
    assertTrue(isElementPresent(by));
}

public boolean isElementPresent(By by) {
    boolean isElementPresent = false;
    int time = 0;
    while (!isElementPresent && time < timeOut) {
        if (isElementPresentNow(by)) {
            isElementPresent = true;
        } else {
            isElementPresent = false;
        }
        sleep(1);
        time++;
    }
    return isElementPresent;
}

// Un petit "hack" qui permet d'ignorer temporairement le timeout.
public boolean isElementPresentNow(By by) {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
    boolean isElementPresent = (driver.findElements(by).size() != 0);
    driver.manage().timeouts().implicitlyWait(timeOut, TimeUnit.MILLISECONDS);
    return isElementPresent;
}

Les nouveaux logs

Désormais, les logs ressemblent maintenant à ça :

Accès à l'URL https://voitures.nc/
Renseignement du texte '107' dans l'élément 'recherche'
Clic sur l'élément 'input[value='OK']'
Clic sur l'élément '//a[contains(., 'Offre')]'
Clic sur l'élément '(//a[contains(@href, 'orderBy=prix')])[1]'
Clic sur l'élément '(//table[contains(@href, 'detail_annonce')]//img)[1]'
ERREUR : le prix affiché est supérieur à 10000

On comprend un peu mieux ce qui s’est passé. Un testeur n’ayant pas lui-même écrit ce test peut, en se concentrant un peu, retracer le scénario. Ca peut suffire, mais une fois encore, si on veut partager nos logs, on se retrouve dépendants de la clarté des sélecteurs.

Le script Selenium niveau big boss : des logs compréhensibles par tout le monde

Jusqu’à maintenant, rien de bien original. Mais nous voulons maintenant aller un peu plus loin, en permettant à toute personne de comprendre parfaitement les logs, sans avoir besoin du moindre bagage HTML et CSS. On pense par exemple aux intervenants fonctionnels qui auraient besoin de lancer les tests automatisés en autonomie et d’analyser leurs résultats. Chaque étape sera détaillée en langage naturel, joliment et proprement, aussi bien que si on les avait décrites nous-mêmes. A ce stade, les logs du test seront aussi clairs que possible, et surtout à peu de frais. Ca vend du rêve ? Bien sûr que non, car c’est gratos ! C’est parti !

Ce que nous n’allons pas faire

Une solution serait d’étoffer chaque méthode de la classe VoituresNcPage par un log spécifique.

public void classerParPrix(){
   logger.info("Classement des produits par prix");
   clickElement(BTN_CLASSER_PAR_PRIX);
}

Pourquoi pas, si vous avez le temps d’écrire ces logs et que vous vous engagez à les maintenir. Mais on va partir du principe que vous voulez gagner du temps et faire au plus simple.

Notre proposition : bye bye le By

Pour identifier et interagir avec les éléments de la page (boutons, liens, champs…), Selenium propose une classe dédiée : By. Elle permet de les sélectionner par xpath, nom de classe CSS, sélecteur CSS, id, texte de lien hypertexte (ou partie de ce texte), name, balise html…

private final By BTN_CLASSER_PAR_PRIX = By.xpath("(//a[contains(@href, 'orderBy=prix')])[1]");

Mais nous allons laisser tomber ce bon vieux By, ou plutôt l’améliorer pour la beauté de vos logs. Nous allons passer par une nouvelle classe, que nous allons appeler « Selecteur ».

// Dans AbstractPage

public class Selecteur {
   public String nom; // C'est cette variable qui va contenir la description de chaque élément en langage naturel !
   public By chemin;

   public Selecteur(String nom, By chemin){
      this.nom = nom;
      this.chemin = chemin;
   }

   public String getNom(){
      return nom;
   }

   public By getChemin(){
      return chemin;
   }
}

Remplacement des By par des Selecteurs

Dans les méthodes

Maintenant, on va modifier nos méthodes de bas niveau qui utilisent la classe By, en la remplaçant par la classe Selecteur. Par exemple :

// Dans AbstractPage

protected void clickElement(Selecteur selecteur) {
    logger.info("Clic sur " + selecteur.getNom());
    assertElementPresent(selecteur);
    driver.findElement(selecteur.getChemin()).click();
}
protected String getPathFromBy(Selecteur selecteur){
    return selecteur.getChemin().toString().split(": ")[1];
}
public void assertElementPresent(Selecteur selecteur) {
    if(!isElementPresent(selecteur.getChemin())){
        logger.error("ERREUR : " + selecteur.getNom() +
                " n'a pas été trouvé(e) sur la page. " +
                " (sélecteur : '" + getPathFromBy(selecteur) + "')");
    }
    assertTrue(isElementPresent(selecteur.getChemin()));
}
[...]

Dans les objets Page

A cette étape, il reste maintenant à transformer les sélecteurs « By » qui se trouvent dans vos objets pages. Et en premier paramètre, à vous de jouer : vous devez décrire, du mieux que vous pouvez, ce qu’est l’objet d’un point de vue fonctionnel ; à quoi il sert. Vous devez le faire concisément, mais surtout précisément, pour éviter toute ambiguïté.

private final Selecteur BTN_CLASSER_PAR_PRIX = new Selecteur("le bouton permettant de classer les articles par prix", By.xpath("(//a[contains(@href, 'orderBy=prix')])[1]"));

Résultats du refacto

Une fois que c’est fait, on reteste pour voir à quoi ressemblent maintenant les logs !

Accès à l'URL https://voitures.nc/
Renseignement du texte '107' dans le champ de recherche
Clic sur le bouton permettant de valider la recherche
Clic sur le lien vers les offres
Clic sur le bouton permettant de classer les articles par prix
Clic sur le bouton permettant de déplier l'annonce n°1
ERREUR : le prix affiché est supérieur à 10000

Là, on a toutes les informations et on comprend tout. Et que se passe-t-il si on regarde, comme au début de l’article, ce que montrent les logs si jamais le champ de recherche a disparu ?

Accès à l'URL https://voitures.nc/
Renseignement du texte '107' dans le champ de recherche
ERREUR : le champ de recherche n'a pas été trouvé(e) sur la page. (sélecteur : 'recherche')

Bien, on comprend aussi.

[BONUS] Le script Selenium niveau serial-bugkiller : le générateur de rapport de bug

Tels quels, vos logs expliqueront ce qu’on fait les automates de test. En changeant peu de choses à la proposition précédente, vos logs détailleront les étapes à suivre pour reproduire leur comportement. Et du coup, vous mettrez un peu moins de temps à rédiger vos rapports de bugs, car votre partie « Etapes pour reproduire » sera déjà écrite par votre automate, et n’importe qui pourra la comprendre, quel que soit son niveau de connaissance du projet.

Rendez-vous sur l'URL https://voitures.nc/
Renseigner le texte '107' dans le champ de recherche
Cliquer sur le bouton permettant de valider la recherche
Cliquer sur le lien vers les offres
Cliquer sur le bouton permettant de classer les articles par prix
Cliquer sur le bouton permettant de déplier l'annonce n°1
ERREUR : le prix affiché est supérieur à 10000

Vous n’aurez peut-être pas besoin de ce type de logs, ceux de l’étape précédente vous suffiront peut-être, mais cela vous donnera peut-être d’autres idées d’utilisations des logs.

Conclusion

Pour conclure, nous pourrions dire qu’il est illusoire de rechercher une Peugeot 107 à 10 000 XPF ou moins.

Mais aussi, que vos logs sont un atout dont vous pouvez tirer une grande valeur, et à peu de frais. Ce que nous avons exploré dans cet article n’est qu’un exemple parmi d’autres de valorisation des logs.

Et vous, comment utilisez-vous vos logs de tests automatisés ? Comment les avez-vous améliorés au fil du temps ?

Crédit image

L’image de couverture est une reprise de Miss Auras (Le Livre rouge), Sir John Lavery (1856-1941).

Gestion du temps : la métaphore de la figue

Priorisation : que faire quand ça semble trop tard ?

Pour ce troisième article sur les métaphores au service du test, nous allons nous pencher une fois de plus sur l’ennemi juré de la qualité : le temps, qui vient souvent avec ses cousins le rush, le stress et la précipitation. Et si une métaphore nous aidait à nous réconcilier avec ce facteur incontrôlable ?

Problématique

Le sprint est presque fini mais rien n’est vraiment prêt. Toute l’équipe est stressée et ne sait plus où donner de la tête. Freeze : c’est peut-être le moment de se calmer un peu et de faire le point sur ce qu’on peut rapidement finaliser. Vous avez besoin d’un déclencheur pour vous sortir la tête du guidon et aller à l’essentiel.

Métaphore

« Récolter les fruits d’un travail » est une métaphore assez commune. En cette fin de sprint ou d’itération, vous et votre équipe êtes en pleine cueillette. Mais vos paniers ne se remplissent pas très vite et vous vous inquiétez car le soleil est en train de se coucher. La lumière décline, les figues sont de moins en moins visibles dans les arbres et l’angoisse de ne rien cueillir habite chacun d’entre vous. Naturellement, à ce stade, ce sont les figues les plus basses que vous devez récolter, peu importe si elles sont petites. Le « low-hanging fruit« , c’est un bénéfice rapide que l’on peut faire en déployant un effort modéré.

Cette métaphore est souvent utilisée dans la littérature agile, et en particulier dans More Agile Testing. Dans l’objectif de livrer de la valeur à chaque sprint, il est parfois intéressant de se focaliser sur ce qui est rapidement faisable plutôt que sur ce qui serait idéal à long terme. On pourrait utiliser cette métaphore en réunion, par exemple pour organiser des postits énumérant des solutions à un problème. Attention tout de même à garder en tête la notion de valeur, afin de ne pas cueillir un fruit pourri…

Un exemple de schéma :

Dans ce graphique structuré autour d’un arbre, l’axe horizontal du représente la valeur ajoutée et l’axe vertical rla difficulté ou la complexité. Les post-its peuvent être classés dans cet arbre pour que l’on puisse visualiser les tâches pouvant rapidement apporter de la valeur. Ces tâches se trouveront donc dans la partie en bas à droite du schéma.

Si vous êtes pressé par le temps, relevez la tête et pensez fruit !

Priorisation bis : le puzzle logiciel au service de la sérénité

Mais fort heureusement, nous ne sommes pas toujours en guerre contre le temps. Côté test, une analyse d’un logiciel par les risques permet de limiter les situations de stress et de faire au mieux en temps limité. Et cela, c’est encore une métaphore qui va nous aider à le partager.

Problématique

En bon choriste de l’ISTQB, vous connaissez par coeur les paroles de « Les défauts sont regroupés » et de « Les tests exhaustifs sont impossibles« . Vos interlocuteurs n’ont peut-être pas envie de vous les entendre chanter encore une fois. Il vous faut rafraîchir cette même idée avec une métaphore.

Métaphore

Janet Gregory compare un logiciel à un puzzle dont on découvre l’image peu à peu, au fur et à mesure où l’on assemble ses pièces. Elle explique qu’il est possible d’obtenir des informations sur le puzzle sans l’assembler en entier, et tant mieux, car cela prendrait un temps fou. Pour tester dans les temps, il faut se concentrer sur les parties du puzzle qui nous intéressent le plus.

Imaginons que notre tableau représente une réplique, peinte par un contemporain, de la fresque de La Création d’Adam, peint par Michel Ange sur le plafond de la Chapelle Sixtine au début du XVIè siècle. Il est spécifié que la réplique doit être la plus fidèle possible à l’original, nous voulons donc tester si cela a été respecté, en maximisant nos chances de trouver d’éventuels défauts. Alors, voici ce que nous allons prendre en compte :

  • La partie du tableau où les doigts d’Adam et de Dieu sont sur le point de se toucher est absolument critique. C’est la plus connue, la plus emblématique de l’oeuvre, celle qui justifie son titre ; c’est l’équivalent du cœur de métier. Il faut qu’elle soit testée.
  • Les visages sont des parties d’un tableau qui peuvent être très intéressantes, mais le moindre détail peut ruiner une expression. On va donc assembler ces parties avec une priorité élevée.
  • On sait que le ciel est quasiment un aplat, il contient peu de détails. Inutile d’assembler beaucoup de pièces pour pouvoir affirmer, avec un niveau de confiance élevé, s’il est fidèle au ciel original.
  • Le paysage où se tient Adam n’est pas aussi uniforme. Il n’est pas utile d’assembler toutes ses pièces si jamais on manque de temps, mais il n’est pas à négliger pour autant.

Les trois puzzles ci-dessous correspondent à des couvertures de test différentes, mais en cas de manque de temps, on comprend que c’est la première qu’il faudra choisir.

Sur la première image, les trous au niveau du ciel et du paysage n’empêchent pas d’étudier les parties critiques du tableau. Sur la seconde image, les trous se situent sur des visages et autres parties très signifiantes de l’oeuvre, ce qui pose problème. Sur la troisième image, la couverture est parfaite car on se trouve face à l’oeuvre entière, sans aucun trou.

Pour approfondir cette métaphore avec son inventrice, rendez-vous sur le blog de Janet Gregory !

Conclusion

Ici, la métaphore nous permet de dynamiser notre exigence de qualité plutôt que de laisser l’exigence de rapidité inhiber nos forces. Même en cas d’urgence, il est profitable de faire une courte pause pour orienter au mieux nos dernières heures disponibles.

Nous espérons que cette petite série d’articles vous aura plu. Nous développerons peut-être à l’avenir d’autres métaphores ; nous espérons avoir bien illustré le fait qu’il s’agit de puissants outils de pensée.

N’hésitez pas à poster vos propres métaphores dans les commentaires !

Découvrez nos autres séries d’articles !

Notre saga du test audiovisuel

Notre série dédiée aux tests de sécurité

Celle dédiée à Protractor

Gestion des connaissances : la métaphore de l’île

« Un vieillard qui meurt, c’est une bibliothèque qui brûle »

Pour ce deuxième article sur les métaphores au service du test, nous allons nous concentrer sur un aspect crucial de tout projet informatique : la gestion des connaissances. Comment faire pour partager les bonnes infos aux bons endroits, de manière à ce que les bonnes personnes puissent les trouver au bon moment ? Et pour commencer, comment donner aux collaborateurs l’envie de transmettre leur savoir d’une part, d’augmenter leurs compétences d’autre part ? Lorsque vous étudiez ces questions avec votre équipe, nous vous proposons de garder à l’esprit une métaphore, qui nous vient des confins du Pacifique Sud. Au passage, merci au Guichet du Savoir pour les recherches bibliographiques sur ce sujet !

Gestion des connaissances : et si on jouait les Néo-Zélandais ?

Problématique

Vous en êtes certain, il y a des trous dans la raquette. Les membres de votre équipe sont excellents dans leur spécialité, mais ne connaissent pas suffisamment le travail les uns des autres et sont incapables de se relayer. Cela peut être un handicap à plusieurs niveaux :

  • fonctionnel, car l’absence d’un membre peut constituer un frein pour l’ensemble de l’équipe
    • Marjolaine est la seule à connaître la nouvelle procédure de mise en qualification, mais est clouée au lit par la dengue pour les deux semaines à venir. Les autres membres de l’équipe, frileux à l’idée de se lancer dans une procédure non documentée, se défendent en disant que ce n’est pas à eux de le faire.
  • relationnel, car l’estime et l’empathie ne sont pas toujours au rendez-vous (surtout si les membres de l’équipe ne travaillent pas au même endroit)
    • Quand le projet prend du retard, Anselme le PO considère que les devs ont codé trop lentement et Polly la team leader considère que les specs trop brouillonnes les ont ralentis.
  • individuel, car les membres de l’équipe pourraient s’épanouir davantage en acquérant de nouveaux savoir-faire
    • Boniface est testeur ; le projet dure depuis des mois et des mois et il se sent enfermé dans une routine, il a le sentiment de ne plus rien apprendre. Il songe parfois à changer de boîte.

Métaphore

Mike Talks est testeur en Nouvelle-Zélande. Cité dans More Agile Testing de Janet Gregory et Lisa Crispin (2014), il s’inspire au travail de l’histoire de son pays.

Dans la lignée des idéaux historiques néo-zélandais, j’encourage tout un chacun à sortir de sa zone de confort au sein de son équipe et s’essayer à de nouvelles choses. Dans un contexte de rareté des ressources et des compétences, ces modes de fonctionnements se sont révélées cruciaux pour les premiers pionniers de Nouvelle-Zélande. De manière générale, les spécialistes étaient amenés à diversifier leurs connaissances pour devenir des « spécialistes généralisants« . [Traduction Hightest]

A propos des pionniers de Nouvelle Zélande, Francine Tolron (source) rapporte effectivement les détails d’une vie quotidienne débrouillarde, émaillée de multiples activités :

Le pionnier […] dut trouver en lui-même ses ressources : construire […] un abri, une baraque de ponga, à partir des stipes de fougères, un toit en feuille de lin ; il lui fallut ramasser la nourriture de la forêt […], brûler les troncs pour fertiliser la terre entre les souches afin de planter du blé qu’il devait moudre sur place. Il fabriquait tout ce dont il avait besoin, depuis le beurre jusqu’aux chandelles et aux briques.

Visualisez-vous en train de fabriquer vos propres chandelles pendant que les briques que vous avez vous-mêmes façonnées sont en train de cuire dans votre four ; il n’y a rien que vous ne puissiez pas apprendre, ni vos collègues. Cela dit, on peut être aussi débrouillard que l’on veut, certains savoir-faire ne s’inventent pas, et les cycles projet ne permettent pas forcément de s’accorder de longues journées d’apprentissage autodidacte. La métaphore de Mike Talks permet donc de mettre l’accent sur les liens indispensable entre les membres de l’équipe. De même que les pionniers de Nouvelle-Zélande, il est nécessaire de développer des compétences secondaires, en s’appuyant sur les compétences les uns des autres. L’équipe projet est comme une île où il est nécessaire de valoriser au maximum chacune des ressources, car les risques de perdre une expertise sont décuplés.

Pour la petite histoire, Mike Talks a mis en action cette idée en travaillant de concert avec un business analyst. D’abord convaincu qu’il lui serait simple de rédiger des expressions de besoins, il s’est finalement rendu compte qu’il s’y prenait mal. D’une part, il n’expliquait pas suffisamment le cœur du problème, d’autre part il partait trop loin dans les détails, empiétant sur la marge de manœuvre des développeurs. Progressivement, monter en compétences dans ce domaine a enrichi ses propres pratiques et a par la suite amélioré la performance de ses échanges avec d’autres business analysts.

Mike Talks a également pu approfondir sa connaissance du métier en allant proactivement à la rencontre des utilisateurs du produit testé. Bâtir une relation de confiance, là où il aurait pu ne rien y avoir, lui a encore permis de gagner en pertinence lors de ses tests.

De l’équipe-île au testeur en forme de T

Cette démarche d’apprentissage a pour conséquence de modeler une expertise en forme de T, de nous transformer en « versatilistes » ou « T-shaped testers » (et non, on ne parle pas d’haltérophilie). Cette image a été développée en 1991 par David Guest dans l’ouvrage The Hunt Is On for the Renaissance Man of Computing, où est évoquée l’image de l’homme de Vitruve dessiné par Léonard de Vinci.

Ici, la barre verticale du T représente les connaissances en test, approfondies par l’expérience, et qui permet au testeur d’exercer au mieux son coeur de métier. C’est la taille du testeur ; plus il est grand, plus il voit loin ; il a en tête de nombreux paysages logiciels, il voit venir les problèmes à l’horizon et a le temps de s’y préparer.

La barre horizontale est quant à elle le symbole des domaines connexes maîtrisés en second plan. C’est l’envergure du testeur, ce qui lui permet de tendre la main et d’attraper, d’assimiler et de valoriser des informations issues d’autres domaines. Ce sont les connaissances métier engrangées au contact des clients, la culture technique acquise au contact des développeurs, les compétences managériales développées au fil des projets.

Et vous, quelle est votre T ? Quel est celui de vos collègues ? Que pouvez-vous vous apporter les uns les autres, de manière à ce que votre île soit la plus vivable possible ?

Conclusion

La métaphore de l’île nous amène à capitaliser les connaissances qui existent au sein d’une équipe, afin d’élargir le champ de compétences de chaque individu. De la même manière qu’une fonctionnalité peut être partiellement couverte par des tests portant sur une autre fonctionnalité, des activités peuvent être sommairement assurées par des personnes dont ce n’est pas le coeur de métier.

La démarche d’apprentissage peut s’accompagner d’une réflexion sur le « nous » de l’équipe. Pour cela, nous vous conseillons d’explorer les ateliers et supports développés par l’UdN (Université du Nous).

Nous vous proposerons prochainement une nouvelle métaphore issue de More Agile Testing, qui nous reliera cette fois au monde agricole… d’ici-là, n’hésitez pas à poster en commentaire les métaphores qui vous semblent précieuses pour illustrer la gestion des connaissances.