Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien får du en interaktiv upplevelse när du skapar en exempellösning steg för steg för att lära dig enhetstestningskoncept.
Den här artikeln handlar om att testa ett .NET Core-projekt. Om du testar ett ASP.NET Core-projekt, se Integrationstester i ASP.NET Core.
Prerequisites
- .NET 10 SDK eller senare versioner.
- Valfri textredigerare eller kodredigerare.
TUnit bygger helt på Microsoft. Testing.Platform (MTP) och stöder inte VSTest. I den här handledningen används MTP-läget för dotnet test, som kräver .NET 10 SDK.
Skapa källprojektet
Öppna ett gränssnittsfönster. Skapa en katalog med namnet unit-testing-with-fsharp för att lagra lösningen. I den här nya katalogen kör du följande kommando för att skapa en ny lösningsfil för klassbiblioteket och testprojektet:
dotnet new sln
Skapa sedan en MathService-katalog . Följande disposition visar katalogen och filstrukturen hittills:
/unit-testing-with-fsharp
unit-testing-with-fsharp.slnx
/MathService
Gör MathService till den aktuella katalogen och kör följande kommando för att skapa källprojektet:
dotnet new classlib -lang "F#"
Ersätt innehållet i Library.fs med en felaktig implementering av matematiktjänsten:
namespace MathService
module MyMath =
let squaresOfOdds (xs: int seq) : int seq = raise (System.NotImplementedException("You haven't written a test yet!"))
Ändra tillbaka katalogen till katalogen unit-testing-with-fsharp. Kör följande kommando för att lägga till klassbiblioteksprojektet i lösningen:
dotnet sln add ./MathService/MathService.fsproj
Skapa testprojektet
Skapa sedan katalogen MathService.Tests. Följande disposition visar katalogstrukturen:
/unit-testing-with-fsharp
unit-testing-with-fsharp.slnx
/MathService
Source Files
MathService.fsproj
/MathService.Tests
TUnit-projektmallarna ingår inte i .NET SDK. Installera dem med följande kommando:
dotnet new install TUnit.Templates
Gör katalogen MathService.Tests till den aktuella katalogen och skapa ett nytt projekt med hjälp av följande kommando:
dotnet new TUnit -lang "F#"
Note
Korta mallnamn är skiftlägeskänsliga. Använd TUnit, inte tunit.
Det här kommandot skapar ett testprojekt som använder TUnit som testramverk. Den genererade filen MathService.Tests.fsproj är ett körbart projekt som refererar till TUnit paketet, som innehåller testramverket, asserteringsbiblioteket och MTP-testlöparen och TUnit.Assertions.FSharp paketet, som lägger till F#-hjälpverktyg för assertioner.
Mallen lägger också till exempeltester. Den här självstudien ersätter dem med sina egna tester i Tests.fs. Ta bort Data-katalogen och filerna GlobalSetup.fs, Tests2.fs och Tests3.fs. F#-projekt listar sina källfiler uttryckligen, så ersätt även ItemGroup som innehåller Compile-objekten i MathService.Tests.fsproj med följande:
<ItemGroup>
<Compile Include="Tests.fs" />
</ItemGroup>
Lägg nu till MathService-klassbiblioteket som ett annat beroende till projektet. Använd kommandot dotnet reference add:
dotnet reference add ../MathService/MathService.fsproj
Följande disposition visar den slutliga lösningslayouten:
/unit-testing-with-fsharp
unit-testing-with-fsharp.slnx
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Test Source Files
MathService.Tests.fsproj
Kör följande kommando i katalogen unit-testing-with-fsharp :
dotnet sln add ./MathService.Tests/MathService.Tests.fsproj
Konfigurera MTP-läget för dotnet-test
Eftersom TUnit inte stöder VSTest dotnet test måste det köras i dess MTP-läge. I katalogen unit-testing-with-fsharp skapar du en global.json fil med följande innehåll:
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
Mer information finns i MTP mode of dotnet test.
Skapa det första testet
Du skriver ett misslyckat test, gör det godkänt och upprepar sedan processen. Ersätt innehållet i Tests.fs med följande kod:
namespace MathService.Tests
open TUnit.Core
open TUnit.Assertions
open TUnit.Assertions.Extensions
open TUnit.Assertions.FSharp.TaskAssert
open MathService
type TestClass () =
[<Test>]
member this.TestMethodPassing() = taskAssert {
do! Assert.That(true).IsTrue()
}
[<Test>]
member this.FailEveryTime() = taskAssert {
do! Assert.That(false).IsTrue()
}
Attributet [<Test>] anger en testmetod som körs av testlöparen. TUnit identifierar testmetoder som är medlemmar i en klass. den identifierar inte funktioner som deklareras med let i en modul. TUnit-assertsatser är asynkrona. Beräkningsuttrycket taskAssert från TUnit.Assertions.FSharp kör ett test som en aktivitet och låter dig invänta varje assertion med do!.
Från katalogen unit-testing-with-fsharp kör du dotnet test för att skapa testerna och klassbiblioteket och sedan köra testerna. TUnit-testprojektet innehåller programmets startpunkt för att köra dina tester.
dotnet test startar testprogrammet med det enhetstestprojekt som du har skapat.
De här två testerna visar de mest grundläggande godkända och underkända testerna.
TestMethodPassing passerar och FailEveryTime misslyckas. Skapa nu ett test för metoden squaresOfOdds. Metoden squaresOfOdds returnerar en sekvens med kvadraterna för alla udda heltalsvärden som ingår i indatasekvensen. I stället för att försöka skriva alla dessa funktioner samtidigt kan du iterativt skapa tester som validerar funktionerna. Om du vill få varje test att gå igenom skapar du de nödvändiga funktionerna för metoden.
Det enklaste testet du kan skriva är att anropa squaresOfOdds med alla jämna tal, där resultatet ska vara en tom sekvens med heltal. Lägg till följande test till TestClass-typen:
[<Test>]
member this.TestEvenSequence() = taskAssert {
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
do! Assert.That<int>(actual).IsEquivalentTo(expected)
}
F# är striktare än C# när det löser metodöverbelastningar, så testet skickar elementtypen till Assert.That<int> för att välja asserterna för en sekvens med heltal.
IsEquivalentTo kontrollerar att båda sekvenserna innehåller samma objekt.
När du kör testet ser du att testet misslyckas. Det beror på att du inte har skapat implementeringen än. Få det här testet att passera genom att skriva den enklaste koden i filen Library.fs i ditt MathService-projekt som fungerar:
let squaresOfOdds xs =
Seq.empty<int>
Kör igen i katalogen dotnet test. Kommandot dotnet test kör en version för MathService-projektet och sedan för MathService.Tests-projektet. När du har skapat båda projekten kör den dina tester. Två tester godkänns nu.
Slutför kraven
Nu när du har gjort ett testpass är det dags att skriva mer. Nästa enkla fall fungerar med en sekvens vars enda udda tal är 1. Talet 1 är enklare eftersom kvadraten 1 är 1. Här är nästa test:
[<Test>]
member public this.TestOnesAndEvens() = taskAssert {
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
do! Assert.That<int>(actual).IsEquivalentTo(expected)
}
Att köra dotnet test misslyckas i det nya testet. Du måste uppdatera metoden squaresOfOdds för att hantera det nya testet. Du måste filtrera bort alla jämna tal från sekvensen för att det här testet ska gå igenom. Du kan göra det genom att skriva en liten filterfunktion och använda Seq.filter:
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
Det finns ytterligare ett steg att gå: upphöj varje udda tal till kvadrat. Börja med att skriva ett nytt test:
[<Test>]
member public this.TestSquaresOfOdds() = taskAssert {
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
do! Assert.That<int>(actual).IsEquivalentTo(expected)
}
Du kan åtgärda testet genom att skicka den filtrerade sekvensen via en mappningsoperation för att beräkna kvadraten för varje udda tal.
let private square x = x * x
let private isOdd x = x % 2 <> 0
let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square
Du har skapat ett litet bibliotek och en uppsättning enhetstester för biblioteket. Du har strukturerat lösningen så att tillägg av nya paket och tester är en del av det normala arbetsflödet. Du koncentrerade dig mest på att lösa programmets mål.