Partager via


Test unitaire des bibliothèques F# dans .NET Core à l’aide de dotnet test et MSTest

Ce tutoriel vous guide tout au long d’une expérience interactive qui crée un exemple de solution pas à pas pour apprendre les concepts de test unitaire. Si vous préférez suivre le didacticiel à l’aide d’une solution prédéfinie, afficher ou télécharger 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 tests d’intégration dans ASP.NET Core.

Création du projet source

Ouvrez une fenêtre shell. Créez un répertoire appelé unit-testing-with-fsharp pour contenir la solution. Dans ce nouveau répertoire, exécutez dotnet new sln pour créer une solution. Cela facilite la gestion de la bibliothèque de classes et du projet de test unitaire. Dans le répertoire de solution, créez un répertoire MathService . Le répertoire et la structure de fichiers jusqu’à présent sont indiqués ci-dessous :

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService

Rendez MathService le répertoire actif et exécutez-le dotnet new classlib -lang "F#" pour créer le projet source. Vous allez créer une implémentation défaillante du service mathématique :

module MyMath =
    let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Revenez au répertoire unit-testing-with-fsharp . Exécutez dotnet sln add .\MathService\MathService.fsproj pour ajouter le projet de bibliothèque de classes à la solution.

Création du projet de test

Ensuite, créez le répertoire MathService.Tests . Le plan suivant montre la structure de répertoires :

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests

Créez le répertoire MathService.Tests dans le répertoire actif et créez un projet à l’aide dotnet new mstest -lang "F#"de . Cela crée un projet de test qui utilise MSTest comme framework de test. Le modèle généré configure l’exécuteur de test dans MathServiceTests.fsproj :

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
  <PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
  <PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</ItemGroup>

Le projet de test nécessite d’autres packages pour créer et exécuter des tests unitaires. dotnet new à l’étape précédente a ajouté MSTest. À présent, ajoutez la bibliothèque de classes MathService comme autre dépendance au projet. Utilisez la commande dotnet reference add :

dotnet reference add ../MathService/MathService.fsproj

Vous pouvez voir l’intégralité du fichier dans le référentiel d’exemples sur GitHub.

Vous disposez de la disposition finale suivante de la solution :

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests
        Test Source Files
        MathServiceTests.fsproj

Exécutez dotnet sln add .\MathService.Tests\MathService.Tests.fsproj dans le répertoire unit-testing-with-fsharp .

Création du premier test

Vous écrivez un test défaillant, faites-le passer, puis répétez le processus. Ouvrez Tests.fs et ajoutez le code suivant :

namespace MathService.Tests

open System
open Microsoft.VisualStudio.TestTools.UnitTesting
open MathService

[<TestClass>]
type TestClass () =

    [<TestMethod>]
    member this.TestMethodPassing() =
        Assert.IsTrue(true)

    [<TestMethod>]
     member this.FailEveryTime() = Assert.IsTrue(false)

L’attribut [<TestClass>] désigne une classe qui contient des tests. L’attribut [<TestMethod>] désigne une méthode de test exécutée par l’exécuteur de test. À partir du répertoire unit-testing-with-fsharp , exécutez dotnet test pour générer les tests et la bibliothèque de classes, puis exécutez les tests. L’exécuteur de test MSTest contient le point d’entrée du programme pour exécuter vos tests. dotnet test démarre l’exécuteur de test à l’aide du projet de test unitaire que vous avez créé.

Ces deux tests montrent les tests de réussite et d’échec les plus élémentaires. My test passe et Fail every time échoue. À présent, créez un test pour la squaresOfOdds méthode. La squaresOfOdds méthode retourne une liste des carrés de toutes les valeurs entières impaires qui font partie de la séquence d’entrée. Au lieu d’essayer d’écrire toutes ces fonctions à la fois, vous pouvez créer des tests itératifs qui valident la fonctionnalité. Effectuer chaque passe de test signifie créer les fonctionnalités nécessaires pour la méthode.

Le test le plus simple que nous pouvons écrire consiste à appeler squaresOfOdds avec tous les nombres pairs, où le résultat doit être une séquence vide d’entiers. Voici ce test :

[<TestMethod>]
member this.TestEvenSequence() =
    let expected = Seq.empty<int> |> Seq.toList
    let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
    Assert.AreEqual(expected, actual)

Notez que la expected séquence a été convertie en liste. La bibliothèque MSTest s’appuie sur de nombreux types .NET standard. Cette dépendance signifie que votre interface publique et vos résultats attendus prennent en charge ICollection plutôt que IEnumerable.

Lorsque vous exécutez le test, vous voyez que votre test échoue. Vous n’avez pas encore créé l’implémentation. Effectuez ce test en écrivant le code le plus simple dans la classe Mathservice qui fonctionne :

let squaresOfOdds xs =
    Seq.empty<int> |> Seq.toList

Dans le répertoire unit-testing-with-fsharp , réexécutez dotnet test . La commande dotnet test exécute une build pour le projet MathService, puis pour le projet MathService.Tests. Après avoir généré les deux projets, il exécute ce test unique. Ça passe.

Remplir les conditions requises

Maintenant que vous avez passé un test, il est temps d’écrire plus. Le cas simple suivant fonctionne avec une séquence dont le seul nombre impair est 1. Le nombre 1 est plus facile, car le carré de 1 est 1. Voici ce prochain test :

[<TestMethod>]
member public this.TestOnesAndEvens() =
    let expected = [1; 1; 1; 1]
    let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
    Assert.AreEqual(expected, actual)

L’exécution dotnet test fait échouer le nouveau test. Vous devez mettre à jour la squaresOfOdds méthode pour gérer ce nouveau test. Vous devez filtrer tous les nombres pairs hors de la séquence pour que ce test réussisse. Vous pouvez le faire en écrivant une petite fonction de filtre et en utilisant Seq.filter:

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd |> Seq.toList

Notez l’appel à Seq.toList. Cela crée une liste, qui implémente l’interface ICollection .

Encore une étape : calculer le carré de chaque nombre impair. Commencez par écrire un nouveau test :

[<TestMethod>]
member public this.TestSquaresOfOdds() =
    let expected = [1; 9; 25; 49; 81]
    let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
    Assert.AreEqual(expected, actual)

Vous pouvez corriger le test en redirigeant la séquence filtrée via une opération de mappage pour calculer le carré de chaque nombre impair :

let private square x = x * x
let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd
    |> Seq.map square
    |> Seq.toList

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

Voir aussi