La toolbox qui donnera une autre dimension à vos tests unitaires

J’entends souvent dire que les tests unitaires sont chronophages, difficiles à écrire ou à comprendre. Après chaque conversation sur le sujet, je me rends compte qu’une grande partie du problème est liée à l’outillage. Même si pour un développeur .net, Visual Studio simplifie les choses, il reste des zones d’ombres

Icons des librairies xUnit, FluentAssertion, AutoFixture et Moq

Le framework de test ?

Le framework de test que vous utiliserez aura un gros impact sur ce que vous serez en mesure d’attendre de vos tests. Depuis plusieurs années, je suis un fan inconditionné de xUnit.

Celui-ci a de très nombreux avantages par rapport à MSTest ou Nunit :

  • Sa simplicité (il y a très peu d'attributs et méthodes à connaitre).
  • Ses performances (rapidité et exécution des tests en parallèle). xUnit est indispensable si vous utilisez la fonctionnalité Live Unit de Visual Studio Enterprise et que vous ne voulez pas passer votre temps à attendre après vos tests.
  • Les théories. Elles permettent de passer très facilement des arguments à une méthode de tests via l'attribut InlineData. Au final : on code moins de tests, mais en fournissant plusieurs jeux d’arguments à une méthode on peut exécuter plus de tests.
  • Les tests d’intégration ASP .net core. Ceux-ci offrent la possibilité de simuler des actions de type GET, POST, PUT, ... etc. sur votre application web. Ils utilisent la classe Setup. Ceci permet de tester l’intégrabilité de la chaîne de rendu de votre site (exemple : sur un site MVC on peut détecter une exception produite par une Vue).

La génération de variables ?

Définir un jeu de tests pour les théories, ou produire du code pour générer des variables aléatoires n’est pas toujours drôle. Cette tâche répétitive et inintéressante au possible peut être confiée à AutoFixture.

Outre sa capacité à générer des objets aléatoires, AutoFixture a un avantage indéniable. Le code qui utilise AutoFixture n’est pas impacté lors de la mise à jour d’un constructeur ou d’une propriété publique. Si vous effectuez le refactoring d’une classe, vous n’avez pas besoin d’effectuer un refactoring des tests.

L’ajout d’AutoFixture.Xunit2 pousse vos tests un cran au-dessus. Il donne accès à l’attribut AutoData. Cet attribut remplace l’attribut InlineData de xUnit. Les arguments des théories peuvent alors être générés de manière aléatoire sans avoir besoin d’écrire le moindre code. Comme avec InlineData, il est possible d’utiliser plusieurs attributs AutoData pour une même théorie.

La lisibilité des résultats ?

Normalement, un test ne devrait contenir qu’une assertion (ce n’est pas moi qui le dis, voir le guide des bonnes pratiques). Dans la réalité, ce n’est pas toujours possible. Quand un test échoue, on ne peut pas savoir quelle assertion a échoué sans consulter le code du test. Ceci devient gênant quand il faut analyser les résultats de tests émis par un serveur de build.

Heureusement, il existe une solution très efficace : FluentAssertions. Cette librairie simplifie l’écriture et la lecture des assertions. Elle comprend aussi de nombreuses méthodes de comparaison d’énumérations, d’objets (comparaison des propriétés une à une, ou vérification de références identiques) … etc.

FluentAssertions est une véritable petite pépite. Je ne connais que depuis quelques mois. Aujourd’hui, je me rends compte du temps gagné et des kilomètres de code que je n’écris plus ;)

Tests et injection de dépendances ?

Pour tester proprement une application qui utilise l’injection de dépendance, il n’y a rien de mieux que le mocking. Cette approche permet de substituer les classes nécessaires au test d’une fonctionnalité par d’autres. Ces classes de substitution n’ont aucun intérêt en dehors de tests. Pour éviter de coder des tonnes et des tonnes de classes dédiées aux tests, il existe des frameworks.

Ma préférence va à Moq:

  • Il est simple à prendre en main.
  • Sa syntaxe est très explicite. Ceci facilite grandement la relecture et la maintenance des tests.

Conclusion

Avec de bonnes librairies, on peut code écrire rapidement des tests facilement exploitables.

Petit rappel de ma toolbox favorite :

Jérémy Jeanson

Comments

You have to be logged in to comment this post.