Bienvenue sur Développement Agile

Référence sur le développement logiciel Agile. Nous traitons de conception, de programmation, de pratiques de génie logiciel, d'essais et d'autres sujets connexes.

Agile Tour 2014 - Les tests et la qualité: moteur de productivité

Publié par Félix-Antoine Bourbonnais, Pascal Roy le mardi 11 novembre 2014 à 00:00

Description

Comment transformer la qualité, les tests et le déploiement en moteur de productivité plutôt qu’en simple poste de dépenses? Portés par Lean et Agile, de grands acteurs (ex.: Google) ont transformé leur département d’assurance qualité pour le placer au coeur du processus de production! Limitez les tests réalisés après l’itération et diminuez la pression sur votre équipe qualité.

  • Présentateurs:  Félix-Antoine Bourbonnais et Pascal Roy
  • Niveau : Débutant
  • Public cible : Tous, spécifiquement Assurance qualité, gestionnaires et équipes de développement.

Présentation

En l'honneur de M. Feathers

Publié par Pascal Roy le jeudi 25 septembre 2014 à 00:00
Michael Feathers

En l’honneur de la visite de Michael Feathers à Montréal et Québec pour sa formation Working Effectively with Legacy Code en novembre, nous avons pensé vous présenter une liste de nos coups de coeur parmi les articles qu’il a publiés au cours des dernières années.

J’ai eu le privilège de travailler avec Michael pendant quelques années en compagnie d’Uncle Bob (Robert C. Martin). Michael possède une capacité impressionnante à synthétiser l’essence même de ce qu’est le développement logiciel, de comprendre les problématiques que nous vivons et proposer des solutions pragmatiques et utilisables au quotidien.

Michael s’intéresse vraiment à tous les aspects du développement logiciel. Pas étonnant que son livre "Working Effectively with Legacy Code" soit reconnu comme le 3e ouvrage le plus influent en Agilité (2011).

Si vous ne le connaissez pas, prenez le temps de le lire. Vous ne le regretterez pas. Bonne lecture!

Pascal Roy, VP
Elapse Technologies

 

Son livre

Working effectively with legacy code book

Vous avez déjà entendu parler de ce livre

C’est un ouvrage marquant du monde de l’Agilité… Si vous devez travailler dans un environnement de code patrimonial (Legacy Code), n’hésitez pas une minute à vous le procurer, car il aura sûrement un impact profond sur votre façon de travailler dans le futur.

Code patrimonial et tests

Getting empirical about Refactoring 
A set of Unit Testing Rules

Langages fonctionnels et OO

Tell Above, and Ask Below - Hybridizing OO and Functional Design 
Functional vs Object Oriented Programming with Michael Feathers

Architecture

The humble dialog box

Vous pouvez également profiter de la présence de Michael ces 3-4 novembre 2014 à Montréal et les 6-7 novembre à Québec et assister à sa formation « Working Effectively with Legacy Code ». C’est une occasion unique de partager avec un des pionniers de l’Agilité.

Ne manquez pas non plus le 5@7 du lundi soir à Montréal où Michael explorera comment les différentes pratiques d’estimation utilisées en Agile peuvent être utilisées pour atteindre des objectifs bien spécifiques au sein de nos organisations.

Démystifier les types de tests

Publié par Félix-Antoine Bourbonnais, Pascal Roy le vendredi 24 janvier 2014 à 00:00
Taxonomie-icone


L’expérience nous a permis de constater qu’il semble y avoir une confusion assez répandue au sein de l’industrie quant à la terminologie et le rôle des différents tests utilisés dans le cadre du développement logiciel Agile.

La plupart des entreprises semblent avoir leur propre terminologie basée sur leur expérience antérieure à l’agilité. La littérature Web présente de multiples versions souvent très disparates des mêmes concepts (e.g. pyramide des tests), ce qui vient probablement ajouter à cette confusion.

Dans ce premier article, nous proposons d’explorer avec vous quels sont les différents types de tests et leurs objectifs de même que la portée des différents niveaux de tests.

 

Thèmes abordés dans cet article

  1. Type versus niveau de tests
  2. Est-ce qu'un type peut être écrit à plusieurs niveaux (ex.: un test d'acceptation unitaire)?
  3. Types de tests (selon l'objectif): Acceptation, Fonctionnel, Performance ...
  4. Niveaux de tests (selon la portée): Bout-en-bout, Système, Intégration, Composante, Unitaire
  5. Autres taxonomies: Boîte noire et blanche, Développeurs VS utilisateur, UI, Validation et vérification (V&V) ..

 

Lire l'article complet

Présentation: Esclave de votre dette technique?

Publié par Félix-Antoine Bourbonnais, Pascal Roy le vendredi 15 novembre 2013 à 12:00

 

Description

Votre code est un trou noir? Chaque fonctionnalité est de plus en plus difficile à développer? Vous ne voulez plus toucher à un module sous peine de voir toute votre énergie aspirée?

Cette présentation vous permettra de prendre conscience de l’impact de la dette technique sur votre quotidien et sur votre capacité à livrer du logiciel fonctionnel et de qualité à chaque itération.

Comment soutenir le même niveau de productivité? Comment garder son codesimple et facile à changer?

La présentation sera en trois volets : identifier ce qu’est la dette et ses impacts, quelles sont les techniques et pratiques pour éviter la « patrimonialite aigüe» (infection d’un système vieillissant) et finalement, comment gérer la dette déjà accumulée, y compris quelques trucs pour votre PO.

Non, la déprime n’est pas le destin de tous les projets vieillissants…

  • Niveau : Tous
  • Public cible : Équipes de développement et gestionnaires

Présentation

Que tester lorsqu'on débute avec BDD?

Publié par Pascal Roy le mardi 5 mars 2013 à 15:27

Tout récemment on me demandait conseil sur la façon de mettre en oeuvre des essais de type BDD ou Behavior-Driven Development dans une équipe de développement. En gros, la personne voulait savoir comment partir du bon pied et quels étaient les pièges à éviter. Voici un extrait de son message:

Pour le BDD, j'aimerais connaître votre opinion et votre vécu. Par exemple:

  • On passe par l'interface?
  • On passe au niveau des contrôleurs (ou couche juste en bas de l'interface si vous préférez)?
  • On passe par les services directement?

J'ai pensé partager ma réponse sous forme d'un billet puisque je trouve que la question est pertinente pour la majorité des équipes qui souhaitent débuter avec le BDD. Voici donc...

Il fut un temps ou le message était de ne pas passer par l'interface utilisateur parce que c'était excessivement coûteux et vraiment difficile à faire. Il y a beaucoup de choses qu'on ne connaissait pas à l'époque et les outils étaient somme toute pas mal misérables... Il y a eu beaucoup d'améliorations des outils mais il y a également eu beaucoup d'avancement au niveau de notre compréhension pour faire face à la complexité accrue de passer par l'interface utilisateur. Pour l'avoir fait dans quelques projets, je peux dire qu'il y a moyen de gérer cette complexité, et de ne pas rendre cela significativement plus complexe que de passer par un API de plus bas niveau.

Soyons clair: si on ne passe pas par l'interface usager, on ne peut être certain à 100% qu'un User Story est "Done Done". Peu importe que l'erreur soit banale parce que la couche UI est très mince et simple (ce qui par ailleurs est plutôt rare dans la vrai vie). Une erreur banale dans cette couche peut être quand même suffisante pour faire en sorte que le user story n'est tout simplement pas fonctionnel. Cela peut être aussi bête qu'un champ qui n'est pas lié au bon contrôle. Du point de vue du client, peu importe la profondeur de l'anomalie, le user story n'est pas fonctionnel et la valeur est nulle…

La décision de ne pas faire d'essais au niveau de la couche graphique est donc laissée à l'appréciation de l'équipe selon le retour sur l'investissement anticipé. De ma propre expérience, je crois qu'il y a moyen de faire ça pour que ce ne soit pas énormément plus coûteux que de passer sous la couche UI. Voici tout de même quelques trucs à garder en tête.

Utiliser le langage d'affaires

Premièrement, les tests doivent être écrits en langage d'affaires et non pas au niveau du l'interface utilisateur. Le langage doit en être un d'intention et ne pas tomber dans le détail d'implémentation. Le détail d'un user story peut changer, mais l'intention reste généralement la même, ce qui fait que la définition des tests eux-mêmes reste assez stable. Ce qui peut changer, ce sont les fixtures (ce qui lie le texte BDD et manipule l'application sous test). Celles-ci devront tenir compte des changements dans les détails de l'application (au niveau de l'interface entre autre).

Voici un cas typique fourni par mon collègue Louis-Philippe Carignan et qui illustre très bien ce que je veux dire.

Mauvais exemple
Étant donné que je suis sur la page de création d'un nouveau projet
Et que ma liste de projets existante est vide
Quand je tape le nom du projet dans le textbox "Nom"
Alors j'appuie sur le bouton "Créer"
Et j'ai une confirmation à la page suivante

Bon exemple
Étant donné que je veux créer un nouveau projet
Et que mon portefeuille de projets est vide
Quand je crée un projet avec le nom "Nouveau projet"
Alors je peux entrer les détails de ce projet

Utiliser un langage de programmation connu de votre équipe

Idéalement, le langage des fixtures devrait être le langage de programmation de l'application. C'est une erreur d'introduire "Yet Another Language" (par exemple Ruby). Oui, les gens peuvent apprendre l'autre langage, mais de façon réaliste, ils en ont déjà bien assez de se garder à jour avec les complexités du domaine, du langage de l'application, de l'OO, des design patterns, etc...  Ajoutons aussi, et c'est beaucoup plus important que ce que les gens croient habituellement, qu'utiliser le langage de l'application permet de se servir des mêmes outils de réingénierie (refactoring) pour maintenir les fixtures, ce qui est essentiel pour que ce code soit aussi facilement modifiable que le code de l'application.

Penser globalement, agir localement

La plus grosse erreur que les gens font, c'est de penser que tous les tests d'acceptation doivent absolument passer par l'interface utilisateur lorsque la décision est prise de procéder de cette façon. C'est tout simplement faux. Par exemple, pour tester un user story qui calculerait un montant selon plusieurs paramètres avec une règle d'affaires complexe, nul besoin de faire tous les cas de tests par le UI. On peut avoir un test qui valide l'interface, comme la mise à jour des champs après avoir lancé le calcul par exemple. Mais tous les cas de tests possibles spécifiés par le client qui concerne la règle d'affaires soujacente pourraient être testés directement au niveau de la classe qui implémente la règle elle-même. Ces tests, qui sont parfois aussi des tests unitaires, peuvent tout simplement être rendus disponibles dans la batterie de tests d'acceptation. Après tout, si le client a pris la peine de spécifier ces cas de tests, il va s'attendre à les voir dans les résultats des tests d'acceptation. Dans la mesure où on a un ou plusieurs tests qui assurent que l'interface permet l'exécution des cas d'utilisation, il est inutile de passer tous les cas de tests par elle si ils peuvent être testés autrement.

Il y a donc lieu, en créant chaque test, de se demander à quel niveau il devrait être implémenté. Il ne s'agit pas de couper les coins ronds, mais bien d'éliminer des charges indirectes inutiles.

Organisation des fixtures

Une des choses qu'une équipe réalisera avec le temps est que l'organisation des fixtures est très importante. Il faut que les développeurs sachent instinctivement où regarder quand il y a une nouvelle fonctionnalité à tester. Plus le projet est gros, plus cela a de l'importance. Une approche par écran (ou contexte d'interaction) est  plus facile qu'une approche par cas d'utilisation car elle permet de créer des fixtures qui sont des abstractions d'écran. C'est un peu la même philosophie qu'on retrouve au niveau du pattern MVP (Model View Presenter) ou le Presenter représente une abstraction de plus haut niveau de l'interface. 

Par exemple, si on a un user story qui modifie l'écran de login, on ne doit pas se poser la question sur l'endroit où se trouve la fixture à mettre à jour. En créant une LoginFixture, on évite que les développeurs répartissent du code de contrôle de l'interface un peu partout parce qu'ils ne savent pas que ça existe ailleurs (un problème qu'on a vécu lors de projets chez certains clients). J'ai déjà parlé de cette approche en plus de détail dans une présentation sur l'ATDD (disponible ici) que j'ai faite pour Agile Québec et Agile Montréal en compagnie de Nicolas Desjardins.

Isoler la complexité des fixtures

N'ayez pas peur d'ajouter une couche d'aide qui cache la complexité d'accéder à l'interface afin de faciliter la vie aux développeurs qui doivent modifier les fixtures. Un exemple serait de la création d'un utilitaire qui facilite l'écriture des fixtures pour contrôler des opérations qui sont asynchrones. On peut aussi isoler les choses qui changent souvent dans l'application pour limiter les endroits où il faudra les changer dans les fixtures.

Quand ç'est bien fait, ça rend le code de tests beaucoup plus stable au point où le changement n'est pas vraiment si pénible que ça. Enfin, pas plus que pour l'application elle-même...

Conclusion

En résumé, pour répondre à la question du départ:

  • Les services peuvent être entièrement testés sans passer par l'interface utilisateur.
  • Si un user story utilise un service, ne testez pas ce dernier par l'interface (il devrait déjà avoir été testé). Assurez-vous plutôt que la couche graphique est capable de le manipuler correctement (entrée/sortie) au niveau de l'interface. Cela limite beaucoup la quantité des tests qui doivent passer par l'interface.
  • Passer par l'interface utilisateur est vraiment la seule façon d'être certain que le user story fonctionne ("Done Done" plutôt que "Most likeky done"). Vous pouvez décider de ne pas le faire, mais faites le en connaissance de cause et ne sous-estimez pas ce que vous perdez à ne pas le faire.
  • L'important est que tous les cas de tests spécifiés par le client soient inclus la suite de tests d'acceptation, mais les tests peuvent être à différents niveaux, quitte à réutiliser certains tests unitaires pour valider certains cas comme les règles d'affaires par exemple.
  • Si un user story utilise plusieurs services, ne validez pas les services eux-mêmes, mais bien que l'interface les pilotent correctement. S'il y a une interaction entre les services, il vaut probablement mieux encapsuler cette interaction dans un service composé de plus haut niveau et tester celui-ci directement.

Comme toujours, il faut être pragmatique. Il n'y a pas qu'une seule "bonne" approche. Ça dépend encore beaucoup du contexte, des technologies utilisées et des compétences de l'équipe. Il y a peut-être encore des environnements qui rendent les tests par l'interface utilisateur excessivement dispendieux. Plusieurs IDE, qui ont un objectif fort louable de rendre le développement d'interface utilisateur plus facile et rapide pour tous, imposent toutefois une architecture qui rend les tests beaucoup plus difficiles à implémenter et maintenir dans une approche BDD.

Archive