4) Améliorer la lisibilité des tests

Les tests sont, pour l'instant, assez difficiles à comprendre :

  • 1 classe de tests avec 948 loc

  • Il y a de la duplication partout

  • Ce qui influe le résultat du test n'est pas mis en évidence

Step 4 : Améliorer la lisibilité des tests

Prenons un exemple pour illustrer cela :

On va essayer d'améliorer la situation en suivant les étapes proposées ci-dessous.

Splitter la classe de tests

  • On commence par déplacer les classes de test à l'extérieur de PartieDeChasseServiceTests

  • Chaque classe de test va maintenant hériter de PartieDeChasseServiceTests

  • On change l'accessibilité (protected) de TimeProvider et AssertLastEvent

  • On peut ensuite sortir chaque classe de tests dans son propre fichier de manière safe

Move to file
  • On se retrouve alors avec une hiérarchie de tests comme suit

Résultat du split
  • On en profite pour séparer les tests unitaires et le test d'acceptation

Séparer Unit et Acceptance
  • On peut aller plus loin en séparant dans chaque fichier les cas passants et non-passants :

Utiliser des Test Data Builders

Prenez le temps de découvrir le pattern expliqué ici.

On va commencer à modifier un premier test en utilisant le pattern et en faisant ressortir ce qui influe sur le résultat du test.

Pour cela on identifie les pré-requis ci-dessous:

Centraliser l'instantiation du Service / Repository

  • On commence par extraire des Fields à partir du test

Extract members
  • Ensuite on remonte les champs dans la class de base

Pull-up members

On peut dès lors refactorer l'ensemble des tests et réduire la duplication.

Écrire son premier Test Data Builder

  • On commence par écrire de manière textuelle ce qu'on souhaite pour instantier la PartieDeChasse

Builder
Generate Code From Usage

  • On dévéloppe les méthodes du Builder

  • On écrit également le ChasseurBuilder

  • Notre test ressemble alors à cela :

Comment aller plus loin ?

Simplifier l'utilisation du repository

  • On crée une méthode nous permettant de faire le setup du repository

  • Alternativement on pourrait écrire une version plus orientée fonctionnelle (Higher Order Functions)

Améliorer les Assertions

De la même manière que pour la partie Arrange, on va améliorer la lisibilité de nos tests en créant des extensions pour nos Assert.

En utilisant FluentAssertions, on peut utiliser le modèle d'extensions décrit ici.

Cela va permettre de se focaliser sur la mutation entrainée sur la PartieDeChasse lors de l'appel à un comportement métier. On commence alors par identifier ce qu'il faut mettre en avant pour ce test :

  • On écrit une première version de ce qu'on voudrait en terme d'assertions

Sample d'assertion
  • On crée une classe d'extensions permettant de renvoyer une instance de PartieDeChasseAssertions

  • On en profite pour ajouter les namespaces Assert et Builders dans le fichier Usings.cs

  • On écrit le code d'assertion

  • On lance notre test : il passe ✅

  • On va maintenant s'assurer du bon fonctionnement de nos assertions en introduisant des mutants à la main dans la classe PartieDeChasseService

    • C'est vital de le faire : les builders et assertions vont être la base de tous nos tests

    • On doit être confiant au maximum vis-à-vis d'eux

  • Le mutant est détecté par notre assert

  • On répète le processus avec d'autres mutants afin de se rassurer

On peut maintenant adapter tous les tests pour utiliser les nouvelles classes créées et étendre les Builders et Assertions.

Nouveau rapport SonarCloud disponible ici.

Reflect

Comparez les tests avant et après cette étape, qu'en pensez-vous ?

On en a profité pour se construire un petit DSL permettant de spécifier nos tests à la gherkin avec la syntaxe Given / When / Then

Last updated

Was this helpful?