Test d’integration AspNetCore sous Net 5

Vandenbussche Julien
Just-Tech-IT
Published in
4 min readMar 24, 2021

Cela fait plusieurs années, que nous mettons en place les pratiques d’ingénieries logicielles, telles que TDD (Test Driven Development) et BDD (Behavior Driven Development). Je ne passerai pas en revue les avantages que ces pratiques apportent dans mes développements quotidien.

Je parlerai juste de certains irritants que j’ai pu rencontrer autour de TDD. Attention, je ne mets en aucun cas cette pratique en cause, je souligne juste qu’à elle seule, elle ne suffit pas, mais qu’elle permet de mettre un pied à l’étrier en ce qui concerne la qualité du code délivré. Et je vous expliquerai pourquoi et comment j’ai mis en place les tests d’integration au sein de ma WebApi sans être impacté par mes dépendances externes à mon API.

En effet, comme vous pouvez le deviner, en ce qui concerne la qualité logiciel je me suis intéressé à la mise en pratique de TDD. Cette pratique m’a apporté beaucoup de chose dans mes développements (Non regression, couverture des fonctionnalités techniques et fonctionnelles etc.). Ces briques étant testées pour la plupart unitairement, lorsque j’estimais avoir fini mes développements, j’exécutais donc ma solution et… Fail… Et oui ce qui peut arriver à ce niveau c’est d’avoir des erreurs d’exécution qui ne sont malheureusement pas remontées lors de mes précèdent tests automatisés… Les erreurs sont souvent liées à des manques de configurations applicatives, du style l’enregistrement d’un type dans mon container IoC (Inversion Of Control)… Il y a aussi un autre irritant qui n’est pas des moindres pour moi c’est la lisibilités des intitulés de mes tests par une population qui n’est pas technique…. Comment pouvoir allier mes tests et le jargon métier connu et compris de tous… C’est là que BDD a tout son intérêt.

Behavior Driven Development

Afin de pourvoir écrire des scenarios et d’implémenter mes tests à partir de ceux-ci, j’utilise SpecFlow ce qui me permet a partir de fichier *.feature d’écrire un scenario compris de tous dans un language standardisé.

voici le package que j’utilise pour ma solution: SpecFlow.NUnit

Nous conviendrons qu’au delta de l’anglais ce scenario est compris de tous. Je résume donc:

  • je voulais pouvoir attaquer mon implementation par des tests
  • je voulais que mes tests soient lisibles de tous

Il me restait donc à mixer tout cela afin de pouvoir réaliser des tests d’intégration au sein de ma WebApi sans être impacté par des dépendances externes…

Test d’integration

J’ai d’un coté mon projet de tests et de l’autre ma WebApi. J’avais par habitude de tester mes controllers mais l’inconvénient , c’est qu’il ma fallu bouchonner le context http cela a complexifié, rendu moins lisible et moins maintenable mon test… Ce que je recherchais aussi avec cette démarche s’était d’avoir un vrai context applicatif de bout en bout avec une vrai context http.

Mes recherches mon amenées au package suivant Microsoft.AspNetCore.Mvc.Testing, ce package va me permettre de configurer et de hoster ma WebApi dans des conditions réelles mais dans un environnement de tests.

Pour commencer, après avoir créer votre projet de test, il faut modifier le .csproj afin de changer le sdk de test:

Avant:

Après:

Voici les packages que j’utilise pour l’implémentations des tests au sein de mes solutions:

Voici à quoi ressemble notre projet de test après c’est quelque modification, vous remarquerez qu’il reference également le projet API a tester (ici: Zoo.Api).

Zoo.Api.Tests

WebApplicationFactory

Toujours dans notre projet de test nous allons créer une classe nous l’appellerons WebFactory, elle héritera de la classe WebApplicationFactory.

IDbContext est un interface custom me permettant de ne pas dépendre de la class DBContext dans mes implementations. Vous pouvez consulter l’implementation d’accès aux données ici et les POCO, DbContext .

Hériter de la classe WebApplicationFactory nous permet d’overrider la méthode protégé ConfigureWebHost(IWebHostBuilder builder).

Mis en place du bouchon pour les accès à la base de données

Initialisation de nos scenarios

J’ai pris l’habitude de créer une classe StepInitialize qui va me permettre d’initialiser le ScenarioContext et de libérer les ressources à la fin du scenario.

Une fois ce travaille réaliser nous pouvons partir sur l’implementation d’un scenario. Ici nous allons simplement tester que notre api nous retourne des ours, et avoir la possibilitée de créer d’enregistrer un ours dans le Zoo.

Les steps associés :

Et voila, le résultat une fois cette succession de tâche réalisé, et ce qu’il faut surtout souligner c’est que vos tests couvrent fonctionnellement votre code.

En conclusion, nous pouvons en déduire qu’il est de plus en plus simple d’intégrer au sein de nos développements la pratique BDD qui nous permet d’implementer nos règles fonctionnelles à partir de scenario défini avec la filière produit. Ceci nous permet de produire un code simple qui répond au besoin énoncé avec des cas de tests concrets et ainsi d’éviter de partir dans une implémentation de code qui ne sera probablement jamais utilisé.

Dans cette article je ne traite pas les dépendances entre une api ou un Service WCF Externe. J’ai cependant implémenté ces cas dans cette solution. Vous trouverez tout cela sur mon github ici.

--

--

Vandenbussche Julien
Just-Tech-IT

Developper/TechLead chez AXA France, DotNet est mon terrain de jeu depuis plusieurs années. Craftman dans l’âme, j’adore échanger autour des sujets technologies