Sdílet prostřednictvím


Testování jednotek knihoven F# pomocí testu dotnet a NUnit

Tento kurz vás provede interaktivním prostředím a podrobným sestavením ukázkového řešení, kde se seznámíte s koncepty testování jednotek. Pokud chcete postupovat podle kurzu pomocí předem připraveného řešení, před zahájením si prohlédněte nebo stáhněte ukázkový kód . Pokyny ke stažení najdete v tématu Ukázky a kurzy.

Tento článek se týká testování projektu .NET Core. Pokud testujete projekt ASP.NET Core, přečtěte si téma Integrační testy v ASP.NET Core.

Požadavky

  • .NET 8 SDK nebo novější verze
  • Textový editor nebo editor kódu podle vašeho výběru.

Vytvoření zdrojového projektu

Otevřete okno příkazového řádku. Vytvořte adresář s názvem unit-testing-with-fsharp pro uložení řešení. V tomto novém adresáři spusťte následující příkaz, který vytvoří nový soubor řešení pro knihovnu tříd a testovací projekt:

dotnet new sln

Dále vytvořte adresář MathService . Následující osnova ukazuje zatím strukturu adresářů a souborů:

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

Nastavte MathService jako aktuální adresář a spuštěním následujícího příkazu vytvořte zdrojový projekt:

dotnet new classlib -lang "F#"

Vytvoříte neúspěšnou implementaci matematické služby:

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

Změňte adresář zpět na adresář unit-testing-with-fsharp . Spuštěním následujícího příkazu přidejte do řešení projekt knihovny tříd:

dotnet sln add .\MathService\MathService.fsproj

Vytvoření testovacího projektu

Dále vytvořte adresář MathService.Tests . Následující osnova ukazuje adresářovou strukturu:

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

Vytvořte adresář MathService.Tests jako aktuální adresář a vytvořte nový projekt pomocí následujícího příkazu:

dotnet new nunit -lang "F#"

Tento příkaz vytvoří testovací projekt, který jako testovací architekturu používá NUnit. Vygenerovaná šablona nakonfiguruje spouštěč testů v MathServiceTests.fsproj:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
  <PackageReference Include="NUnit" Version="4.1.0" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

Testovací projekt vyžaduje k vytvoření a spuštění testů jednotek další balíčky. dotnet new v předchozím kroku jsme přidali NUnit a adaptér testu NUnit. Teď do projektu přidejte knihovnu tříd MathService jako jinou závislost. Použijte příkaz dotnet reference add:

dotnet reference add ../MathService/MathService.fsproj

Celý soubor můžete zobrazit v úložišti ukázek na GitHubu.

Máte následující konečné rozložení řešení:

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

V adresáři unit-testing-with-fsharp spusťte následující příkaz:

dotnet sln add .\MathService.Tests\MathService.Tests.fsproj

Vytvoření prvního testu

Napíšete jeden neúspěšný test, uděláte ho úspěšným, a pak tento proces zopakujete. Otevřete UnitTest1.fs a přidejte následující kód:

namespace MathService.Tests

open System
open NUnit.Framework
open MathService

[<TestFixture>]
type TestClass () =

    [<Test>]
    member this.TestMethodPassing() =
        Assert.That(true, Is.True)

    [<Test>]
     member this.FailEveryTime() = Assert.That(false, Is.True)

Atribut [<TestFixture>] označuje třídu, která obsahuje testy. Atribut [<Test>] označuje testovací metodu, kterou spouští spouštěč testů. Z adresáře unit-testing-with-fsharp spusťte dotnet test pro sestavení testů a knihovny tříd a poté testy spusťte. Spouštěč testů NUnit obsahuje vstupní bod programu pro spuštění testů. dotnet test spustí spouštěč testů pomocí projektu testu jednotek, který jste vytvořili.

Tyto dva testy ukazují ty nejzákladnější testy, které prošly a neprošly. My test projde a Fail every time selže. Teď vytvořte test pro metodu squaresOfOdds . Metoda squaresOfOdds vrátí sekvenci čtverců všech lichých celočíselných hodnot, které jsou součástí vstupní sekvence. Místo toho, abyste se pokusili najednou napsat všechny tyto funkce, můžete iterativním způsobem vytvořit testy, které funkci ověřují. Aby každý test prošel, musíte vytvořit pro metodu potřebnou funkcionalitu.

Nejjednodušším testem, který můžete napsat, je volat squaresOfOdds se všemi sudými čísly, kde by výsledek měl být prázdná posloupnost celých čísel. Tady je tento test:

[<Test>]
member this.TestEvenSequence() =
    let expected = Seq.empty<int>
    let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
    Assert.That(actual, Is.EqualTo(expected))

Všimněte si, že expected sekvence se převede na seznam. Architektura NUnit spoléhá na mnoho standardních typů .NET. Tato závislost znamená, že vaše veřejné rozhraní a očekávané výsledky podporují ICollection spíše než IEnumerable.

Když test spustíte, uvidíte, že váš test selže. Je to proto, že jste ještě nevytvořili implementaci. Proveďte tento test tak, že napíšete nejjednodušší kód ve třídě Library.fs v projektu MathService, který funguje:

let squaresOfOdds xs =
    Seq.empty<int>

V adresáři unit-testing-with-fsharp spusťte dotnet test znovu. Příkaz dotnet test spustí sestavení projektu MathService a poté projektu MathService.Tests. Po sestavení obou projektů spustí testy. Nyní prošly dva testy.

Splnění požadavků

Nyní, když jste úspěšně prošli jedním testem, je čas napsat více testů. Další jednoduchý případ funguje se sekvencí, jejíž jediné liché číslo je 1. Číslo 1 je jednodušší, protože čtverec 1 je 1. Tady je další test:

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

Spuštění dotnet test selže při novém testu. Chcete-li tento nový test zpracovat, je nutné aktualizovat metodu squaresOfOdds . Aby test prošel, musíte odebrat všechna sudá čísla ze sekvence. Můžete to udělat tak, že napíšete malou funkci filtru a použijete Seq.filter:

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd

Existuje ještě jeden krok: umocněte každé z lichých čísel. Začněte napsáním nového testu:

[<Test>]
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.That(actual, Is.EqualTo(expected))

Test můžete opravit propojením filtrované sekvence pomocí operace mapování pro výpočet čtverce každého lichého čísla:

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

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

Vytvořili jste malou knihovnu a sadu jednotkových testů pro tuto knihovnu. Řešení jste strukturují tak, aby přidání nových balíčků a testů bylo součástí normálního pracovního postupu. Většinu času a úsilí jste se zaměřili na řešení cílů aplikace.

Viz také