Les tests, oui, mais pas n’importe comment !

Nicolas Poste
4 min readSep 14, 2018

--

Cet article fait partie d’une série nommée “Maximisez les chances de réussir votre projet informatique”.

Celui-ci aborde le thème des tests, indispensables à toute réussite, mais qui, lorsqu’ils sont mal mis en place, sont responsables de nombreux échecs.

Nous parlerons :

  • De TDD, BDD
  • Des bonnes pratiques pour la réalisation des tests unitaires
  • Des tests fonctionnels automatisés
  • Des raisons pour lesquelles des tests mal mis en place pourraient être à l’origine d’échecs

TDD ou BDD ?!

Et bien, les deux en fait…

Les gains de l’approche TDD ne sont plus à démontrer.

L’approche BDD, qui étend celle du TDD, fait apparaître la notion de comportement, peu abordée dans la première définition du TDD. Son adoption est préconisée car elle met l’accent sur la collaboration entre les différents intervenants et donne plus de visibilité au métier. Les tests sont plus robustes et compréhensibles par chacun.

📝 “Le TDD fait correctement est le BDD. Le BDD est le TDD réalisé correctement.”

Contrairement aux idées reçues, TDD/BDD, ce n’est pas uniquement faire des tests unitaires. Des tests de plus haut niveau ont également leur place dans le TDD/BDD.

Zoom sur le TDD

Le TDD, c’est une discipline de développement incrémentale et minimaliste : on n’écrit que le strict nécessaire. Le TDD respecte ces trois règles, décrites par Robert C Martin :

  1. Vous devez écrire un test qui échoue avant d’écrire n’importe quel code de production
  2. Vous ne devez pas écrire plus d’un test nécessaire pour échouer; les problèmes de compilation sont considérés comme des échecs
  3. Vous ne devez pas écrire plus de code de production que nécessaire pour réussir un test unitaire qui échoue

Le développement se fait alors en trois étapes :

  1. On crée un nouveau test unitaire qui échoue
  2. On écrit du code de production qui fait que le test passe
  3. On nettoie, on refactor pour rendre plus propre. Les tests doivent toujours passer

Double Loop

On différencie tout de même les tests unitaires des tests sur le comportement, mais l’un n’empêche pas l’autre, bien au contraire. Je tiens justement à parler d’une pratique moins connue, celle du “Double Loop”.

https://jmauerhan.wordpress.com/talks/double-loop-tdd-bdd-done-right/

Rappels concernant la réalisation des tests unitaires

Il est bon de rappeler que les tests unitaires doivent suivre les principes FIRST :

  • [F]ast, rapides, quelques milli-secondes maximum
  • [I]solated, isolés, aucun test ne dépend d’un autre, pour qu’une collection de tests puisse être jouée dans n’importe quel ordre
  • [R]epeatable, répétables, joués N fois, produisent toujours le même résultat
  • [S]elf-validating, auto-validés, chaque test doit être capable de déterminer si son résultat est celui attendu ou non. Il doit déterminer s’il a réussi ou échoué. Il ne doit pas y avoir d’interprétation manuelle des résultats
  • [T]imely, opportuns, ils doivent être écrits à peu près en même temps que le code qu’ils testent. Le TDD les écrit même avant

Les tests fonctionnels automatisés

Les tests fonctionnels doivent être proches du code sans être dans un formalisme trop proche de l’implémentation. Idéalement être présents dans le même projet, ils doivent rester de haut niveau et être compréhensibles par les clients ou utilisateurs.

💡 Les outils tels que FitNesse disposent de bonnes fonctionnalités, mais sont trop souvent mal utilisés et dès lors, je déconseille leur utilisation. De nos jours, il existe bien plus simple et performant, exemple avec Cucumber

L’erreur à ne pas commettre, c’est d’investir majoritairement sur ces tests. Ce sont souvent les plus longs à s’exécuter et les plus fragiles. Les tests unitaires, puis d’intégration, doivent constituer les premiers harnais de tests.

https://martinfowler.com/bliki/TestPyramid.html

💡 La présence de tests fonctionnels automatisés en surnombre et fragiles constituent l’un des symptômes d’un code malade. Voir mon article Allo docteur, je crois que mon code est malade

👉 Un bon condensé d’informations sur ces tests a été publié par l’Institut Agile, dans un billet nommé Tests fonctionnels automatisés

Pourquoi des tests mal mis en place pourraient-ils être à l’origine d’échecs ?

Les tests garantissent que l’application fait ce qui est attendu d’elle.

Des tests unitaires mal mis en place, trop proches de l’implémentation par exemple, introduisent une lourde charge au niveau de la maintenance, ralentissant ainsi considérablement le travail des développeurs. Ceux-ci seraient alors tentés de désactiver quelques tests, ce qui fragilise l’application.

⚠️ Alors que cela partait d’une plutôt bonne intention, dans l’une de mes missions, une autre ESN avait sensibilisé ses collaborateurs à obtenir un taux de couverture de code correct. Les développeurs se sont alors mis à tester les getters et setters des POJOs, à écrire des tests qui passaient par bon nombre de méthodes sans en tester le résultat, …
Attention à la course de la couverture de code ! Ce n’est pas la bonne façon de procéder, il faut privilégier l’approche TDD/BDD qui abouti automatiquement à une couverture de code plus que satisfaisante

Des tests fonctionnels mal mis en place peuvent eux aussi être à l’origine de sérieux ralentissements de l’équipe de développement. Mal utilisés, ces tests ralentissent le pipeline de livraison de quelques heures cruciales : le développeur n’a pas de retour rapide sur son dernier commit/push, ce qui l’oblige à se replonger dans son code alors qu’il est parti sur autre chose entre temps.

Pour plus d’informations

Consultez le reste de la série “Maximisez les chances de réussir votre projet informatique” :

--

--

Nicolas Poste

CTO @ Ceetiz, passionné par le Software Craftsmanship, les aspects techniques, d'automatisation pour gagner en efficacité, Docker, ...