Comment rédiger des tests de qualité

Problèmes courants dans l'écriture de tests

Sur un précédent projet, la plupart des membres étaient nouveaux et peu familiers avec l'écriture de tests. Cela a conduit à deux problèmes récurrents : des noms de tests vagues et un code de test difficile à lire.

Des noms de tests imprécis

Les développeurs débutants ne pensent pas naturellement au triptyque Given-When-Then. Ils se contentent souvent d'un simple should_xxx, sans préciser les conditions. Résultat : le nom du test ne décrit pas ce qu'il vérifie.

J'ai découvert sur StackOverflow un modèle intéressant : GivenA_WhenB_ThenC. Je l'ai adapté avec deux améliorations :

  • Supprimer les mots-clés : on peut omettre "Given" et "When" si la convention est respectée (le premier segment est le Given, le deuxième le When, le dernier le Then).
  • Séparateurs : le camelCase devient illisbile quand le nom est long. J'utilise ___ (triple underscore) comme séparateur. Deux underscores sont trop courts, quatre sont inutiles.

Exemples tirés d'un exercice DDD :

parking_order_is_natural_order___park_cars_by_parking_assistant___car_parked_to_correct_parking_lot_in_turn
car_is_already_took___take_back_car_with_used_receipt___exception_is_thrown
parking_lot_is_available___park_a_car_by_parking_assistant___receipt_returned
car_is_parked___take_back_car_with_invalid_receipt___exception_is_thrown

Astuce : Si le Given est absent ou trivial, on peut le sauter mais le séparateur reste obligatoire : ___xxx_xxx___xxx_xxx.

Bénéfices

  • Uniformisation des noms de tests dans l'équipe (langage commun). On peut ajouter une vérification statique pour détecter les noms non conformes.
  • Obligation de réfléchir au contexte (Given), à l'action (When) et au résultat attendu (Then).
  • Lecture facilitée : le cerveau distingue immédiatement les trois parties sans avoir à interpréter.

Inconvénient

Les noms deviennent longs. Il faut apprendre à les conciser en évitant les répétitions.

J'appelle cette approche la nommage GWT (Given-When-Then).

Code de test illisible

Beaucoup de développeurs créent des méthodes createX() qui masquent toute la construction, y compris les sous-objets :

Foo createFoo() {
   Bar bar = new Bar();
   return new Foo(bar, valeur1, valeur2);
}

En lisant un test qui utilise createFoo(), on ne sait pas comment valeur1 et valeur2 sont définies. Modifier cette méthode peut casser plusieurs tests de façon inattendue.

Ma solution actuelle :

  1. Exposer explicitement les données importantes dans le test. Par exemple, si valeur1 et valeur2 influencent la logique, passez-les en paramètre directement :
@Test
void ___quand_voiture_deja_prise___recuperer_avec_ticket_utilise___exception_levee() {
   Bar bar = creerBar();
   Foo foo = creerFoo(valeur1, valeur2, bar);
   // agir
   // vérifier
}

Avantage : on voit immédiatement les données sans avoir à naviguer dans le code.

  1. Ne lister que les données qui comptent pour le test. Si un champ n'est pas utilisé dans la logique testée, donnez-lui une valeur par défaut dans la méthode de construction.

Pourquoi ne pas utiliser un builder ?

J'ai déjà essayé les builders, mais le code devient verbeux. La méthode createFoo(paramètres) est plus concise et facile à lire.

Étiquettes: tests GivenWhenThen Java Nommage de tests Readabilité

Publié le 19 juillet à 23h42