Enhetstestning av C# med MSTest och .NET
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. Om du föredrar att följa självstudien med hjälp av en färdig lösning kan du visa eller ladda ned exempelkoden innan du börjar. Instruktioner för nedladdning finns i Exempel och självstudier.
Den här artikeln handlar om att testa ett .NET Core-projekt. Om du testar ett ASP.NET Core-projekt kan du läsa Integreringstester i ASP.NET Core.
Förutsättningar
Skapa källprojektet
Öppna ett gränssnittsfönster. Skapa en katalog med namnet unit-testing-using-mstest för att lagra lösningen. I den här nya katalogen kör du dotnet new sln
för att skapa en ny lösningsfil för klassbiblioteket och testprojektet. Skapa en PrimeService-katalog . Följande disposition visar katalogen och filstrukturen hittills:
/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService
Gör PrimeService till den aktuella katalogen och kör dotnet new classlib
för att skapa källprojektet. Byt namn på Class1.cs till PrimeService.cs. Ersätt koden i filen med följande kod för att skapa en misslyckad implementering av PrimeService
klassen:
using System;
namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first.");
}
}
}
Ändra tillbaka katalogen till katalogen unit-testing-using-mstest . Kör dotnet sln add
för att lägga till klassbiblioteksprojektet i lösningen:
dotnet sln add PrimeService/PrimeService.csproj
Skapa testprojektet
Skapa katalogen PrimeService.Tests. Följande disposition visar katalogstrukturen:
/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Gör katalogen PrimeService.Tests till den aktuella katalogen och skapa ett nytt projekt med .dotnet new mstest
Det nya dotnet-kommandot skapar ett testprojekt som använder MSTest som testbibliotek. Mallen konfigurerar testlöparen i filen PrimeServiceTests.csproj :
<ItemGroup>
<PackageReference Include="MSTest" Version="3.2.0" />
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.10.1" />
</ItemGroup>
Testprojektet kräver andra paket för att skapa och köra enhetstester. dotnet new
i föregående steg lade du till nödvändiga MSTest-paket och verktyg för kodtäckningsrapportering.
PrimeService
Lägg till klassbiblioteket som ett annat beroende till projektet. dotnet add reference
Använd kommandot:
dotnet add reference ../PrimeService/PrimeService.csproj
Du kan se hela filen i exempellagringsplatsen på GitHub.
Följande disposition visar den slutliga lösningslayouten:
/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Test Source Files
PrimeServiceTests.csproj
Ändra till katalogen unit-testing-using-mstest och kör dotnet sln add
:
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
Skapa det första testet
Skriv ett misslyckat test, gör det godkänt och upprepa sedan processen. Ta bort UnitTest1.cs från katalogen PrimeService.Tests och skapa en ny C#-fil med namnet PrimeService_IsPrimeShould.cs med följande innehåll:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;
namespace Prime.UnitTests.Services
{
[TestClass]
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService;
public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}
[TestMethod]
public void IsPrime_InputIs1_ReturnFalse()
{
bool result = _primeService.IsPrime(1);
Assert.IsFalse(result, "1 should not be prime");
}
}
}
Attributet TestClass anger en klass som innehåller enhetstester. Attributet TestMethod anger att en metod är en testmetod.
Spara den här filen och kör dotnet test
för att skapa testerna och klassbiblioteket och kör sedan testerna. MSTest-testlöparen innehåller programmets startpunkt för att köra dina tester. dotnet test
startar testkören med det enhetstestprojekt som du har skapat.
Testet misslyckas. Du har inte skapat implementeringen än. Gör det här testet genom att skriva den enklaste koden i klassen PrimeService
som fungerar:
public bool IsPrime(int candidate)
{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Please create a test first.");
}
Kör igen i katalogen dotnet test
unit-testing-using-mstest. Kommandot dotnet test
kör en version för PrimeService
projektet och sedan för PrimeService.Tests
projektet. När du har skapat båda projekten körs det här enskilda testet. Den passerar.
Lägg till fler funktioner
Nu när du har gjort ett testpass är det dags att skriva mer. Det finns några andra enkla fall för primtal: 0, -1. Du kan lägga till nya tester med attributet TestMethod, men det blir snabbt omständligt. Det finns andra MSTest-attribut som gör att du kan skriva en uppsättning liknande tester. En testmetod kan köra samma kod men har olika indataargument. Du kan använda attributet DataRow för att ange värden för dessa indata.
I stället för att skapa nya tester använder du dessa två attribut för att skapa ett enda datadrivet test. Det datadrivna testet är en metod som testar flera värden som är mindre än två, vilket är det lägsta primtal. Lägg till en ny testmetod i PrimeService_IsPrimeShould.cs:
[TestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);
Assert.IsFalse(result, $"{value} should not be prime");
}
Kör dotnet test
och två av dessa tester misslyckas. Om du vill att alla tester ska godkännas ändrar if
du -satsen i början av IsPrime
metoden i filen PrimeService.cs :
if (candidate < 2)
Fortsätt att iterera genom att lägga till fler tester, fler teorier och mer kod i huvudbiblioteket. Du har den färdiga versionen av testerna och den fullständiga implementeringen av biblioteket.
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 har koncentrerat dig mest på att lösa programmets mål.