Introduction

Les tests unitaires ajoutés dans nos applications .NET nous aident à vérifier que le code source se comporte comme attendu et qu’il n’y a pas de régressions notamment lorsque l’on ajoute des modifications aux différentes « couches » de l’application. Néanmoins, ce type de tests a une approche et un périmètre complètement technique et c’est au développeur de les concevoir et de les mettre en place, pour assurer le bon comportement de l’application.

SpecFlow va apporter une approche plus fonctionnelle à nos tests. Grâce à SpecFlow, on va pouvoir créer d’autres types de tests (tests fonctionnels, user acceptance tests, end to end tests) pour chacune des fonctionnalités, en utilisant un langage compréhensible pour tout le monde et pas seulement pour les développeurs, et en faisant le lien entre ce langage compréhensible (Gherkin) et le langage technique (C#) avec lequel les tests sont mis en oeuvre.

Ainsi, avec ce langage, même une personne sans connaissance technique peut comprendre les tests SpecFlow. Le développeur n’ayant plus qu’à mettre en place le « code behind » en C# lié à chacune des « phrases Gherkin» de nos tests. Ceci est notamment conceptualisé par l’approche Behavior Driven Development.

 

Installation

Pour utiliser SpecFlow dans nos projets avec Visual Studio, on doit rajouter l’extension Specflow :

Installation

Grâce à cette extension on va pouvoir :

  • Créer des projets de tests de type SpecFlow dans notre solution.
  • Editer des fichiers de type « feature » contenant les tests mis en place avec le langage Gherkin
  • Utiliser le framework « SpecFlow+ Runner » pour exécuter nos tests.
  • Générer des reports HTML avec les résultats de nos tests, dans un format clair et facile à lire pour tout le monde.

Création d’un projet de test SpecFlow

Pour créer un projet de test SpecFlow dans la solution, il suffit d’ajouter un nouveau projet en sélectionnant « SpecFlow Projet » comme modèle de création de projet :

Add new project

Lors de la création du projet, il faut sélectionner la version de .NET ainsi que le framework de test qui sera en charge d’exécuter les tests. Specflow propose son framework « Specflow+ Runner », mais on peut aussi sélectionner xUnit par exemple.

En activant le flag « Add FluentAssertions library », on pourra utiliser les méthodes de la librairie FluentAssertions pour mettre en place nos tests :

Create a new SpecFlow project

Structure d’un projet Specflow

Après la création de notre projet de test, on a une structure comme celle-ci :

Structure

Les parties plus importantes sont :

  • Le dossier « Features » contenant les fichiers de test écrits avec la syntaxe « Gherkin ».
  • Le dossier « Steps » contenant les fichiers de StepDefinitions avec les classes et les méthodes C# auxquelles les « phrases » utilisées dans les fichiers Features sont liées.
  • Le dossier « Hooks » pouvant contenir les classes et les méthodes C# avec une logique additionnelle aux tests (par exemple, code à exécuter avant ou après de chaque test).

 

Fichiers « feature » et syntaxe Gherkin

On a un fichier .feature pour chacune des fonctionnalités qu’on veut tester. Dans ce fichier, on mettra en place l’ensemble de tests liés à cette fonctionnalité.

Ces fichiers sont écrits avec la syntaxe Gherkin qui permet de décrire les tests avec le pattern GivenWhenThen.

Dans un fichier .feature on a :

  • La description de la fonctionnalité à tester avec le mot clé Feature initial.
  • Pour chaque test, la description du test avec le mot clé Scenario, et dans le test, la liste de pass (steps) :
    • Les conditions initiales du test avec le mot clé Given
    • L’action à exécuter avec le mot clé When
    • La vérification du résultat avec le mot clé Then

Exemple :

Feauture

On peut avoir autant de steps que l’on veut, en utilisant le mot clé And :

Feature

Fichiers StepDefinitions

Les fichiers « step definitions » font le lien entre les features décrites avec la syntaxe Gherkin et le code C# qu’on veut tester.  Pour faire fonctionner ce lien, on utilisera ces attributs SpecFlow :

  • Attribut [Binding] à rajouter aux classes C# contenant les méthodes qui mettent en place chaque step.
  • Attributs [Given], [When] et [Then] à rajouter à chaque méthode liée à un step. Pour identifier le step, le paramètre de l’attribut aura le même libellé que celui du fichier « feature».

Exemple :

Copy to Clipboard

Dans ce code, on peut noter que :

  • Le binding pour les paramètres d’entrée de chaque méthode est fait par SpecFlow à partir de l’expression régulière utilisée dans le libellé de l’attribut.
  • Dans la classe, on peut déclarer des variables private pour garder temporairement les données des tests (objet de l’application à tester, valeurs initiales des tests, résultat d’exécution, etc.)

 

Tests SpecFlow avec des données complexes

Dans l’exemple précèdent, on a vu comment SpecFlow fait le binding entre les données de test incluses dans les fichiers features et les paramètres d’entrée de méthodes C#. Néanmoins, ces données sont de type simple (string, int, etc), tandis qu’on a souvent besoin de tester avec des données plus complexes comme des objets incluant plusieurs propriétés, ou des collections d’objets.

Dans ce cas, on peut utiliser les tableaux SpecFlow dans les fichiers features, et les binder dans les méthodes C# en utilisant le type Table dans le namespace TechTalk.SpecFlow.

Voici un exemple d’un tableau SpecFlow dans le fichier features pour renseigner les propriétés d’un objet complexe :

Feature

Côté C#, on peut récupérer les données comme ceci :

Code C#

On peut noter que la classe Table considère toutes les données comme « string », donc, il faut faire une conversion lorsque le type C# de la propriété n’est pas string.

Pour simplifier nos tests, SpecFlow propose les helpers de la librairie SpecFlow.Assist. Cette librairie contient des méthodes d’extension qui permettent de transformer un objet de type Table vers un objet ou collection d’objets du type souhaité :

  • Méthode CreateInstance : elle crée un objet du type indiqué à partir d’un objet de type Table. Exemple :

Feature

Code C#

  • Méthode CreateSet : elle crée une collection d’objets du type indiqué à partir d’un objet de type Table. Exemple :

Feature

Code C#

Exécution de tests

Pour exécuter les tests avec Visual Studio, rien ne change par rapport aux tests unitaires. Il suffit d’afficher la fenêtre Test Explorer, et de lancer l’exécution de tests :

Test Explorer

Si l’on utilise Azure DevOps pour la partie Test du processus d’intégration continue, on peut également ajouter une étape d’exécution normale de ces tests dans les pipelines considérés, comme ici :

Pipeline

Génération de documentation avec SpecFlow+ LivingDoc

SpecFlow+ LivingDoc est un outil qui permet de générer un report en HTML pour l’ensemble de tests SpecFlow et les résultats d’exécution.

L’extension SpecFlow installée dans Visual Studio n’inclut pas cet outil par défaut. Il faut l’installer avec cette commande depuis la console :

Commande

Pour générer le report, il faut se placer dans le répertoire de sortie du projet de test :

Commande

Et lancer la commande de génération avec ces 2 paramètres :

  • test-assembly: Nom du fichier dll de l’assembly de test
  • t: Fichier json généré par SpecFlow avec les résultats d’exécution de tests.

Commande

Cette commande génére le fichier LivingDoc.html avec le report complet des tests :

Résultat

Résultat

Il est possible aussi de générer ces reports lors de l’exécution des pipelines par Azure DevOps. Pour ceci, il faut d’abord installer l’extension SpecFlow+ LivingDoc dans l’organisation Azure DevOps :

https://marketplace.visualstudio.com/items?itemName=techtalk.techtalk-specflow-plus

Dans le pipeline, il faut ajouter une étape SpecFlow+ comme celle-ci :

Pipeline

Les paramètres de cette étape sont détaillés dans :

https://docs.specflow.org/projects/specflow-livingdoc/en/latest/Generating/Configuring-the-Build-Step-in-YAML.html

Il faut noter que cette étape ne déclenche pas l’exécution de tests. Elle se limite à générer la documentation HTML à partir des fichiers features du projet de tests, et à ajouter les résultats de l’exécution de tests d’une étape précédente.

Dès que l’exécution du pipeline est terminée, on obtient le report des tests dans l’onglet SpecFlow+ LivingDoc sous le menu Overview :

Résultat

 

Conclusion

SpecFlow nous permet de créer des tests depuis une perspective fonctionnelle, avec un langage compréhensible par tout le monde. Il nous offre de plus des outils pour générer de façon dynamique des reports HTML avec les détails de nos tests et les résultats d’exécution.

 

Sources

https://specflow.org/

Ne ratez plus aucunes actualités avec la newsletter mensuelle de SoftFluent