oct.
2012
Du micro-BDD avec les labels
Vous connaissez le "Behavior-Driven Development" (BDD) ?
C'est une méthode de spécification et de test, qui consiste à décrire des scénarios sous la forme de triplets "conditions initiales" / "action" / "résultat attendu" (Given... / When... / Then...).
Différents frameworks (Cucumber, EasyB, JNario...) facilitent la mise en place de ce pattern en proposant notamment une syntaxe spécifique (DSL), et offrent de nombreuses fonctionnalités fort pratiques.
Mais si seule la formalisation "Given / When / Then" vous intéresse dans vos tests unitaires, il suffit d'utiliser... les labels Java.
Oui, vous avez bien lu : les labels. Ceux-là mêmes qui permettent d'habitude de sortir des boucles imbriquées :
outerLoop: // Label for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (i==j) { break outerLoop; } } }
D'après la JLS § 14.7, Il est possible de poser un label sur n'importe quel statement, c'est-à-dire instruction ou bloc d'instruction exécutable - et donc, sur un bloc de code délimité par des accolades.
label: { ... }
Avec un peu (beaucoup) d'imagination, il est donc possible de bricoler un micro-DSL orienté BDD dans nos tests :
@Test public void testAdd() { int i; int j; int result; Given: // Two numbers 1 and 4 { i = 1; j = 4; } When: // I add the two numbers { result = i + j; } Then: // The result should be 5 { Assert.assertEquals(5, result); } }
D'accord, cela ne casse pas trois pattes à un lamellirostre commun, mais cet usage créatif des bons vieux labels m'a paru suffisamment intéressant pour vous en toucher un mot.
Une dernière remarque : les blocs délimités par les accolades définissent des scopes à part entière ; une variable déclarée à l'intérieur n'est pas visible en-dehors. Cela nous oblige à déclarer les variables globales au début de la méthode (ce qui améliore, à mon avis, la lisibilité du test), mais permet d'utiliser des variables locales au besoin.
Bon petit déjeuner et à bientôt !
Commentaires
C'est bon ça, merci :-)
J'utilisais déjà le formalisme Given-When-Then au travers de commentaires. Le découpage en scopes est séduisant. Par contre, les labels Java n'étant pas utilisés autrement que pour structurer le test, le compilateur renvoie des warnings du type : "The label Given is never explicitly referenced". Pour ne pas avoir ces warnings, il faudrait annoter chaque méthode de test avec @SuppressWarnings, ou bien ajouter des "break Given;", ce qui dans les deux cas ne m'emballe pas vraiment. Dommage, car l'idée était sympathique.