Testowanie jednostkowe bibliotek języka F# na platformie .NET Core przy użyciu testów dotnet i MSTest

Ten samouczek przeprowadzi Cię przez interaktywne środowisko tworzenia przykładowego rozwiązania krok po kroku, aby poznać pojęcia dotyczące testowania jednostkowego. Jeśli wolisz wykonać czynności opisane w samouczku przy użyciu wstępnie utworzonego rozwiązania, przed rozpoczęciem wyświetl lub pobierz przykładowy kod . Aby uzyskać instrukcje dotyczące pobierania, zobacz Przykłady i samouczki.

Ten artykuł dotyczy testowania projektu platformy .NET Core. Jeśli testujesz projekt ASP.NET Core, zobacz Testy integracji w programie ASP.NET Core.

Tworzenie projektu źródłowego

Otwórz okno powłoki. Utwórz katalog o nazwie unit-testing-with-fsharp w celu przechowywania rozwiązania. W tym nowym katalogu uruchom polecenie dotnet new sln , aby utworzyć nowe rozwiązanie. Ułatwia to zarządzanie zarówno biblioteką klas, jak i projektem testów jednostkowych. W katalogu rozwiązania utwórz katalog MathService . Do tej pory przedstawiono strukturę katalogów i plików:

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

Utwórz aplikację MathService jako bieżący katalog i uruchom polecenie dotnet new classlib -lang "F#" , aby utworzyć projekt źródłowy. Utworzysz nieudaną implementację usługi matematycznej:

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

Zmień katalog z powrotem na katalog unit-testing-with-fsharp . Uruchom polecenie , dotnet sln add .\MathService\MathService.fsproj aby dodać projekt biblioteki klas do rozwiązania.

Tworzenie projektu testowego

Następnie utwórz katalog MathService.Tests . W poniższym konspekcie przedstawiono strukturę katalogów:

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

Utwórz katalog MathService.Tests jako bieżący katalog i utwórz nowy projekt przy użyciu polecenia dotnet new mstest -lang "F#". Spowoduje to utworzenie projektu testowego, który używa biblioteki MSTest jako platformy testowej. Wygenerowany szablon konfiguruje moduł uruchamiający testy w pliku 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>

Projekt testowy wymaga innych pakietów do tworzenia i uruchamiania testów jednostkowych. dotnet new w poprzednim kroku dodano narzędzie MSTest i moduł uruchamiający MSTest. Teraz dodaj bibliotekę MathService klas jako inną zależność do projektu. dotnet add reference Użyj polecenia :

dotnet add reference ../MathService/MathService.fsproj

Cały plik można zobaczyć w repozytorium przykładów w witrynie GitHub.

Masz następujący końcowy układ rozwiązania:

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

Wykonaj polecenie dotnet sln add .\MathService.Tests\MathService.Tests.fsproj w katalogu unit-testing-with-fsharp .

Tworzenie pierwszego testu

Napisz jeden test zakończony niepowodzeniem, wykonaj go pomyślnie, a następnie powtórz ten proces. Otwórz plik Tests.fs i dodaj następujący kod:

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)

Atrybut [<TestClass>] określa klasę zawierającą testy. Atrybut [<TestMethod>] określa metodę testową uruchamianą przez moduł uruchamiający testy. W katalogu unit-testing-with-fsharp wykonaj polecenie dotnet test , aby skompilować testy i bibliotekę klas, a następnie uruchomić testy. Moduł uruchamiający testy MSTest zawiera punkt wejścia programu w celu uruchomienia testów. dotnet test uruchamia moduł uruchamiający testy przy użyciu utworzonego projektu testów jednostkowych.

Te dwa testy pokazują najbardziej podstawowe testy z przekazywaniem i niepowodzeniem. My test przechodzi i Fail every time kończy się niepowodzeniem. Teraz utwórz test dla squaresOfOdds metody . Metoda squaresOfOdds zwraca listę kwadratów wszystkich nieparzystnych wartości całkowitych, które są częścią sekwencji wejściowej. Zamiast próbować napisać wszystkie te funkcje jednocześnie, można iteracyjne tworzyć testy sprawdzające funkcjonalność. Utworzenie każdego testu z powodzeniem oznacza utworzenie niezbędnych funkcji dla metody .

Najprostszym testem, który możemy napisać, jest wywołanie squaresOfOdds ze wszystkimi liczbami parzystymi, gdzie wynikiem powinna być pusta sekwencja liczb całkowitych. Oto ten 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)

Zwróć uwagę, że expected sekwencja została przekonwertowana na listę. Biblioteka MSTest korzysta z wielu standardowych typów platformy .NET. Ta zależność oznacza, że interfejs publiczny i oczekiwane wyniki obsługują ICollection , a nie IEnumerable.

Po uruchomieniu testu zobaczysz, że test zakończy się niepowodzeniem. Implementacja nie została jeszcze utworzona. Wykonaj ten test, pisząc najprostszy kod w Mathservice klasie, która działa:

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

W katalogu unit-testing-with-fsharp ponownie uruchom polecenie dotnet test . Polecenie dotnet test uruchamia kompilację dla MathService projektu, a następnie dla MathService.Tests projektu. Po utworzeniu obu projektów zostanie uruchomiony ten pojedynczy test. Przechodzi.

Spełnianie wymagań

Teraz, gdy wykonano jeden test, nadszedł czas, aby napisać więcej. Następny prosty przypadek działa z sekwencją, której jedyną nieparzystą liczbą jest 1. Liczba 1 jest łatwiejsza, ponieważ kwadrat 1 wynosi 1. Oto następny 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)

Wykonanie testu kończy się niepowodzeniem dotnet test . Aby obsłużyć ten nowy test, należy zaktualizować metodę squaresOfOdds . Aby wykonać ten test, należy przefiltrować wszystkie liczby parzyse z sekwencji. Można to zrobić, pisząc małą funkcję filtru i używając polecenia Seq.filter:

let private isOdd x = x % 2 <> 0

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

Zwróć uwagę na wywołanie metody Seq.toList. Spowoduje to utworzenie listy, która implementuje ICollection interfejs.

Jest jeszcze jeden krok, aby przejść: kwadrat każdej z nieparzystnych liczb. Zacznij od napisania nowego testu:

[<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)

Test można naprawić, potokując filtrowaną sekwencję za pomocą operacji mapy w celu obliczenia kwadratu każdej liczby nieparzysta:

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

Utworzono małą bibliotekę i zestaw testów jednostkowych dla tej biblioteki. Rozwiązanie zostało ustrukturyzowane tak, aby dodawanie nowych pakietów i testów było częścią normalnego przepływu pracy. Większość czasu i nakładu pracy na rozwiązywaniu celów aplikacji koncentrujesz się przez większość czasu i wysiłku.

Zobacz też