13 Fév 2015

Dojo #15

Pour ce quinzième Dojo, nous avons choisi de travailler autour des concepts SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation, Dependency inversion).

Le sujet

en français et l’original

Déroulement du Dojo

WP_20150204_13_34_42_Pro

Technologies utilisées par les équipes :

  • C#,
  • Java

Briefing de 10 minutes avec rappel des concepts SOLID, réalisation des trois premiers exercices sur le modèle : codage, échanges.

Exercice 1 : UnicodeFileToHtmTextConverter

L’enjeu de cet exercice est de pouvoir maitriser l’entrée de la méthode de conversion de texte. Pour cela deux techniques :

  • Utiliser un jeu de fichiers connu et les utiliser dans les tests
  • Ajouter une surcharge à la méthode pour exploiter un flux d’octets et modifier la méthode de conversion pour utiliser cette nouvelle méthode

Tout le monde a été d’accord pour dire que l’objet du test n’était pas de tester la méthode de conversion en HTML fournie par le framework mais de tester l’utilisation du fichier fait dans la méthode “ConvertToHtml”. Nous avons également évoqué une vision différente de la conception sur la classe. En effet, le chemin d’accès au fichier n’est nécessaire que dans la méthode “ConvertToHtml”. Ajouter ce paramètre à la méthode permet ensuite de produire différentes surcharges orientées conversion de flux et non conversion de fichier.

Exercice 2 : TirePressureMonitoringSystem

Le problème dans ce code est l’utilisation d’un nombre aléatoire. Lors de l’exécution de nos tests unitaires, ce nombre n’est pas connu. Il faut donc trouver une technique pour connaitre la pression retournée par le capteur. Nous avons identifié deux techniques similaires avec des implémentations différentes. Dans un premier temps, nous extrayons de la classe “Sensor” une interface “ISensor” définissant la méthode “PopNextPressurePsiValue”. Ensuite nous ajoutons un constructeur à la classe “Alarm” pour injecter le capteur de pression de type “ISensor” nécessaire à son fonctionnement. Le constructeur par défaut de “Alarm” injecte une instance de “Sensor” comme initialement. Nous implémentons enfin la classe de test. C’est là que nous avons deux options :

  • La première, assez artisanale, est relativement adaptée si nous débutons avec les Mocks (bouchons) et que l’interface n’expose pas beaucoup de méthodes. Elle consiste à créer une classe implémentant l’interface “ISensor” dont le constructeur prend en paramètre la valeur de pression que l’on souhaite.
  • La seconde nécessite la connaissance d’une bibliothèque de Mock, dans notre cas une majorité de personnes connaissent Moq. Une librairie de Mock permet de définir les méthodes, ainsi que les réponses, nécessaires à notre code. Dans l’idéal, il faudra tester que les méthodes définies, et aucune autre, ont bien été appelées.

Découverte pour certains, usage courant pour d’autres, cet exercice a été l’occasion de rappeler qu’un test unitaire devait être reproductible unitairement donc indépendant du temps (comme le random ou la date système) ou de l’environnement.
Les utilisateurs de framework d’injection de dépendances tel Unity sont assez familiers du concept et ne perçoivent parfois pas complètement l’importance de cette approche et des frameworks associés pour la testabilité de notre code.

IMG_20150204_135210

Exercice 3 : TicketDispenser

Cet exercice cible l’utilisation des variables statiques dans notre code. Nous avons eu globalement deux axes :

  • Tester une succession d’appels et valider les numéros des tickets
  • Tester la fonctionnalité de base : deux tickets n’ont pas le même numéro et que le ticket plus récent a un numéro supérieur au précédent

Ces deux approches sont radicalement différentes. Dans la première, il faut réussir à maitriser la valeur initiale du compteur et écrire des tests indépendants. C’est souvent ce second point qui a conduit à invalider nos tests car ils étaient dépendants de leur ordre d’exécution respectif. A l’opposé, la seconde approche permet de réaliser simplement un test qui valide le fonctionnement souhaité sans se préoccuper de l’implémentation interne du générateur de numéros de ticket.
Ces trois exercices nous ont permis de comprendre ce que nous testions pour :

  1. tester notre code et pas celui des frameworks que nous utilisons
  2. avec une approche, préférable, en mode boite noire

Nous avons aussi vu un des intérêts des frameworks d’injection de dépendances, un pattern de mise en œuvre et l’utilisation d’un framework de mocks.

Share