Delen via


Eenheid testen C# in .NET met behulp van dotnet-test en xUnit

Deze zelfstudie laat zien hoe u een oplossing bouwt die een eenheidstestproject en broncodeproject bevat. Als u de zelfstudie wilt volgen met behulp van een vooraf gebouwde oplossing, bekijkt of downloadt u de voorbeeldcode. Zie Voorbeelden en zelfstudies voor downloadinstructies.

De oplossing maken

In deze sectie wordt een oplossing gemaakt die de bron- en testprojecten bevat. De voltooide oplossing heeft de volgende mapstructuur:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.cs
        PrimeService.csproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.cs
        PrimeServiceTests.csproj

De volgende instructies bevatten de stappen voor het maken van de testoplossing. Zie Opdrachten voor het maken van een testoplossing voor instructies voor het maken van de testoplossing in één stap.

  • Open een shellvenster.

  • Voer de volgende opdracht uit:

    dotnet new sln -o unit-testing-using-dotnet-test
    

    Met de dotnet new sln opdracht maakt u een nieuwe oplossing in de map unit-testing-using-dotnet-test .

  • Wijzig de map in de map unit-testing-using-dotnet-test .

  • Voer de volgende opdracht uit:

    dotnet new classlib -o PrimeService
    

    Met de dotnet new classlib opdracht maakt u een nieuw klassebibliotheekproject in de map PrimeService . De nieuwe klassebibliotheek bevat de code die moet worden getest.

  • Wijzig de naam van Class1.cs in PrimeService.cs.

  • Vervang de code in PrimeService.cs door de volgende code:

    using System;
    
    namespace Prime.Services
    {
        public class PrimeService
        {
            public bool IsPrime(int candidate)
            {
                throw new NotImplementedException("Not implemented.");
            }
        }
    }
    
  • Met de voorgaande code wordt:

    • Hiermee wordt een NotImplementedException bericht met een bericht weergegeven dat het niet is geïmplementeerd.
    • Wordt verderop in de zelfstudie bijgewerkt.
  • Voer in de map unit-testing-using-dotnet-test de volgende opdracht uit om het klassebibliotheekproject toe te voegen aan de oplossing:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Maak het project PrimeService.Tests door de volgende opdracht uit te voeren:

    dotnet new xunit -o PrimeService.Tests
    
  • De bovenstaande opdracht:

    • Hiermee maakt u het project PrimeService.Tests in de map PrimeService.Tests . Het testproject gebruikt xUnit als testbibliotheek.
    • Hiermee configureert u de testrunner door de volgende <PackageReference />elementen toe te voegen aan het projectbestand:
      • Microsoft.NET.Test.Sdk
      • xunit
      • xunit.runner.visualstudio
      • coverlet.collector
  • Voeg het testproject toe aan het oplossingsbestand door de volgende opdracht uit te voeren:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Voeg de PrimeService klassebibliotheek toe als een afhankelijkheid aan het project PrimeService.Tests :

    dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj  
    

Opdrachten voor het maken van de oplossing

In deze sectie vindt u een overzicht van alle opdrachten in de vorige sectie. Sla deze sectie over als u de stappen in de vorige sectie hebt voltooid.

Met de volgende opdrachten maakt u de testoplossing op een Windows-computer. Werk voor macOS en Unix de ren opdracht bij naar de versie van het besturingssysteem om de naam van ren een bestand te wijzigen:

dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Volg de instructies voor 'Vervang de code in PrimeService.cs door de volgende code' in de vorige sectie.

Een test maken

Een populaire benadering in testgestuurde ontwikkeling (TDD) is het schrijven van een (mislukte) test voordat de doelcode wordt geïmplementeerd. In deze zelfstudie wordt gebruikgemaakt van de TDD-benadering. De IsPrime methode kan worden aangeroepen, maar is niet geïmplementeerd. Een testoproep mislukt IsPrime . Met TDD wordt een test geschreven die bekend is dat het mislukt. De doelcode wordt bijgewerkt om de testpas te maken. U blijft deze aanpak herhalen, een mislukte test schrijven en vervolgens de doelcode bijwerken om door te geven.

Werk het project PrimeService.Tests bij:

  • Verwijder PrimeService.Tests/UnitTest1.cs.
  • Maak een PrimeService.Tests/PrimeService_IsPrimeShould.cs-bestand .
  • Vervang de code in PrimeService_IsPrimeShould.cs door de volgende code:
using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    public class PrimeService_IsPrimeShould
    {
        [Fact]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            var primeService = new PrimeService();
            bool result = primeService.IsPrime(1);

            Assert.False(result, "1 should not be prime");
        }
    }
}

Het [Fact] kenmerk declareert een testmethode die wordt uitgevoerd door de testloper. Voer in de map PrimeService.Tests de opdracht uit dotnet test. De dotnet-testopdracht bouwt beide projecten en voert de tests uit. De xUnit-testloper bevat het programmainvoerpunt om de tests uit te voeren. dotnet test start de testloper met behulp van het eenheidstestproject.

De test mislukt omdat IsPrime deze niet is geïmplementeerd. Schrijf met behulp van de TDD-benadering alleen voldoende code, zodat deze test is geslaagd. Werk IsPrime bij met de volgende code:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Voer dotnet test uit. De test is geslaagd.

Meer tests toevoegen

Voeg priemnummertests toe voor 0 en -1. U kunt de test die u in de vorige stap hebt gemaakt, kopiëren en kopieën maken van de volgende code om 0 en -1 te testen. Maar doe het niet, want er is een betere manier.

var primeService = new PrimeService();
bool result = primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");

Het kopiëren van testcode wanneer alleen een parameter verandert, resulteert in codeduplicatie en test-bloat. Met de volgende xUnit-kenmerken kunt u een suite met vergelijkbare tests schrijven:

  • [Theory] vertegenwoordigt een reeks tests die dezelfde code uitvoeren, maar verschillende invoerargumenten hebben.
  • [InlineData] kenmerk geeft waarden op voor deze invoer.

In plaats van nieuwe tests te maken, past u de voorgaande xUnit-kenmerken toe om één theorie te maken. Vervang de volgende code:

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
    var primeService = new PrimeService();
    bool result = primeService.IsPrime(1);

    Assert.False(result, "1 should not be prime");
}

met de volgende code:

[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);

    Assert.False(result, $"{value} should not be prime");
}

In de voorgaande code [Theory] kunt [InlineData] u verschillende waarden testen die kleiner zijn dan twee. Twee is het kleinste priemnummer.

Voeg de volgende code toe na de klassedeclaratie en vóór het [Theory] kenmerk:

private readonly PrimeService _primeService;

public PrimeService_IsPrimeShould()
{
    _primeService = new PrimeService();
}

Uitvoeren dotnet testen twee van de tests mislukken. Als u alle tests wilt laten slagen, werkt u de IsPrime methode bij met de volgende code:

public bool IsPrime(int candidate)
{
    if (candidate < 2)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Voeg na de TDD-benadering meer mislukte tests toe en werk vervolgens de doelcode bij. Bekijk de voltooide versie van de tests en de volledige implementatie van de bibliotheek.

De voltooide IsPrime methode is geen efficiënt algoritme voor het testen van de primaliteit.

Aanvullende bronnen