Effectuer des tests unitaires de C# avec NUnit et .NET Core

Ce didacticiel vous guide pas à pas dans la création d’un exemple de solution pour apprendre les concepts des tests unitaires. Si vous préférez suivre le didacticiel à l’aide d’une solution prédéfinie, affichez ou téléchargez l’exemple de code avant de commencer. Pour obtenir des instructions de téléchargement, consultez Exemples et didacticiels.

Cet article concerne le test d’un projet .NET Core. Si vous testez un projet ASP.NET Core, consultez les tests d’intégration dans ASP.NET Core.

Prérequis

  • Kit SDK .NET Core 2.1 (ou version ultérieure).
  • Un éditeur de texte ou un éditeur de code de votre choix.

Création du projet source

Ouvrez une fenêtre d’interpréteur de commandes. Créez un répertoire appelé unit-testing-using-nunit qui contiendra la solution. Dans ce nouveau répertoire, exécutez la commande suivante afin de créer un fichier solution pour la bibliothèque de classes et le projet de test :

dotnet new sln

Ensuite, créez un répertoire PrimeService. La structure de répertoire et de fichiers est la suivante :

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /PrimeService

Accédez au répertoire PrimeService et exécutez la commande suivante pour créer le projet source :

dotnet new classlib

Renommez Class1.cs en PrimeService.cs. Créez une implémentation défaillante de la classe PrimeService :

using System;

namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Accédez de nouveau au répertoire unit-testing-using-nunit. Exécutez la commande suivante pour ajouter le projet de la bibliothèque de classes à la solution :

dotnet sln add PrimeService/PrimeService.csproj

Création du projet de test

Ensuite, créez le répertoire PrimeService.Tests. La structure du répertoire est illustrée ci-dessous :

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

Accédez au répertoire PrimeService.Tests et créez un projet à l’aide de la commande suivante :

dotnet new nunit

La commande dotnet new crée un projet de test qui utilise NUnit comme bibliothèque de test. Le modèle généré configure Test Runner dans le fichier PrimeService.Tests.csproj :

<ItemGroup>
  <PackageReference Include="nunit" Version="3.13.3" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
</ItemGroup>

Le projet de test a besoin d’autres packages pour créer et exécuter des tests unitaires. La dotnet new commande de l’étape précédente a ajouté le Kit de développement logiciel (SDK) de test Microsoft, l’infrastructure de test NUnit et l’adaptateur de test NUnit. Maintenant, ajoutez la bibliothèque de classes PrimeService en tant qu’une autre dépendance au projet. Utiliser la commande dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.csproj

Vous pouvez consulter le fichier dans son intégralité dans le dépôt d’exemples sur GitHub.

La solution finale se présente comme suit :

/unit-testing-using-nunit
    unit-testing-using-nunit.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeService.Tests.csproj

Exécutez la commande suivante dans le répertoire unit-testing-using-nunit :

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Création du premier test

Vous écrivez un test défaillant, faites-le passer, puis répétez le processus. Dans le répertoire PrimeService.Tests, renommez le fichier UnitTest1.cs en PrimeService_IsPrimeShould.cs, puis remplacez tout son contenu par le code suivant :

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestFixture]
    public class PrimeService_IsPrimeShould
    {
        private PrimeService _primeService;

        [SetUp]
        public void SetUp()
        {
            _primeService = new PrimeService();
        }

        [Test]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var result = _primeService.IsPrime(1);

            Assert.IsFalse(result, "1 should not be prime");
        }
    }
}

L’attribut [TestFixture] désigne une classe qui contient des tests unitaires. L’attribut [Test] indique une méthode qui est une méthode de test.

Enregistrez ce fichier et exécutez la dotnet test commande pour générer les tests et la bibliothèque de classes et exécuter les tests. Le Test Runner NUnit contient le point d’entrée de programme qui permet d’exécuter vos tests. dotnet test démarre le Test Runner à l’aide du projet de test unitaire que vous avez créé.

Votre test échoue. Vous n’avez pas encore créé l’implémentation. Faites passer le test en écrivant le code le plus simple dans la PrimeService classe qui fonctionne :

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Dans le répertoire unit-testing-using-nunit, réexécutez dotnet test. La commande dotnet test exécute une build pour le projet PrimeService puis pour le projet PrimeService.Tests. Une fois que vous avez généré les deux projets, il exécute ce test unique. Le test réussit.

Ajout de fonctionnalités supplémentaires

Maintenant que vous avez fait réussir un test, le moment est venu d’écrire plus de code. Il existe quelques autres cas simples pour des nombres premiers : 0, -1. Vous pouvez ajouter de nouveaux tests avec l’attribut [Test], mais cela devient vite fastidieux. D’autres attributs NUnit vous permettent d’écrire une suite de tests similaires. Un attribut [TestCase] permet de créer une suite de tests qui exécutent le même code, mais qui ont des arguments d’entrée différents. Vous pouvez utiliser l’attribut [TestCase] pour spécifier des valeurs pour ces entrées.

Au lieu de créer de nouveaux tests, appliquez cet attribut pour créer un test piloté par les données unique. Le test piloté par les données est une méthode qui teste plusieurs valeurs inférieures à deux, qui est le plus petit nombre premier :

[TestCase(-1)]
[TestCase(0)]
[TestCase(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);

    Assert.IsFalse(result, $"{value} should not be prime");
}

Exécutez dotnet test, et deux de ces tests échouent. Pour que tous les tests réussissent, changez la clause if au début de la méthode Main dans le fichier PrimeService.cs :

if (candidate < 2)

Continuez à itérer en ajoutant d’autres tests, théories et code dans la bibliothèque principale. Vous disposez de la version finale des tests et de l’implémentation complète de la bibliothèque.

Vous avez créé une petite bibliothèque et un ensemble de tests unitaires pour cette bibliothèque. Vous avez également structuré la solution afin que l’ajout de nouveaux packages et tests fait partie du flux de travail standard. Vous avez concentré la plupart de votre temps et de vos efforts sur la résolution des objectifs de l’application.