Megosztás a következőn keresztül:


C# egységtesztelés a .NET-ben dotnet-teszt és xUnit használatával

Ez az oktatóanyag bemutatja, hogyan hozhat létre egységtesztprojektet és forráskódprojektet tartalmazó megoldást. Ha előre összeállított megoldással szeretné követni az oktatóanyagot, tekintse meg vagy töltse le a mintakódot. A letöltési utasításokért tekintse meg példákat és oktatóanyagokat.

A megoldás létrehozása

Ebben a szakaszban létrejön egy megoldás, amely tartalmazza a forrás- és tesztprojekteket. A kész megoldás a következő könyvtárstruktúrával rendelkezik:

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

Az alábbi utasítások a tesztmegoldás létrehozásának lépéseit ismertetik. A tesztelési megoldás egy lépésben történő létrehozásához szükséges utasításokért tekintse meg a parancsokat.

  • Nyisson meg egy parancssor ablakot.

  • Futtassa a következő parancsot:

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

    A dotnet new sln parancs létrehoz egy új megoldást a unit-testing-using-dotnet-test könyvtárban.

  • Módosítsa a könyvtárat a unit-testing-using-dotnet-test mappára.

  • Futtassa a következő parancsot:

    dotnet new classlib -o PrimeService
    

    A dotnet new classlib parancs létrehoz egy új osztálytárprojektet a PrimeService mappában. Az új osztálykódtár tartalmazza a tesztelni kívánt kódot.

  • Nevezze át a(z) Class1.cs fájlt a következőképpen: PrimeService.cs.

  • Cserélje le a PrimeService.cs kódját a következő kódra:

    using System;
    
    namespace Prime.Services
    {
        public class PrimeService
        {
            public bool IsPrime(int candidate)
            {
                throw new NotImplementedException("Not implemented.");
            }
        }
    }
    

    A kód jelenleg egy NotImplementedException hibát dob, de az oktatóanyag későbbi részében végrehajtja a metódust.

  • A unit-testing-using-dotnet-test könyvtárban futtassa a következő parancsot az osztálytár projektjének a megoldáshoz való hozzáadásához:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Hozza létre a PrimeService.Tests projektet a következő parancs futtatásával:

    dotnet new xunit -o PrimeService.Tests
    

    Az előző parancs létrehozza a PrimeService.Tests projektet a PrimeService.Tests könyvtárban. A tesztprojekt az xUnitot használja teszttárként. A parancs úgy is konfigurálja a tesztfuttatót, hogy hozzáadja a következő <PackageReference />elemeket a projektfájlhoz:

    • Microsoft.NET.Test.Sdk
    • xunit
    • xunit.runner.visualstudio
    • coverlet.collector
  • Adja hozzá a tesztprojektet a megoldásfájlhoz az alábbi parancs futtatásával:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Adja hozzá az PrimeService osztálytárat függőségként a PrimeService.Tests projekthez:

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

A megoldás létrehozásához használt parancsok

Ez a szakasz az előző szakasz összes parancsát összegzi. Kihagyhatja ezt a szakaszt, ha elvégezte az előző szakasz lépéseit.

Az alábbi parancsok létrehozzák a tesztmegoldást egy Windows-gépen. MacOS és Unix esetén frissítse a parancsot a ren fájl átnevezésének operációs rendszerének ren verziójára:

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

Kövesse az előző szakaszban található "A kód cseréje PrimeService.cs a következő kódra" című szakasz utasításait.

Teszt létrehozása

A tesztalapú fejlesztés (TDD) egyik népszerű módszere egy (sikertelen) teszt írása a célkód implementálása előtt. Ez az oktatóanyag a TDD-megközelítést használja. A IsPrime metódus hívható, de nem implementálható. A teszthívás IsPrime sikertelen. A TDD-vel olyan tesztet ír, amelyről ismert, hogy sikertelen. Ezután frissítenie kell a célkódot, hogy a teszt sikeres legyen. Folytatja ezt a módszert, hogy újra és újra írásra kerüljön egy sikertelen teszt, majd frissíti a célkódot, hogy az megfeleljen.

Frissítse a PrimeService.Tests projektet:

  • Törölje a PrimeService.Tests/UnitTest1.cs.

  • Hozzon létre egy PrimeService.Tests/PrimeService_IsPrimeShould.cs fájlt.

  • Cserélje le a PrimeService_IsPrimeShould.cs kódját a következő kódra:

    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 shouldn't be prime");
            }
        }
    }
    

Az [Fact] attribútum deklarál egy tesztmetódust, amelyet a tesztfuttató futtat. A PrimeService.Tests mappából futassa a dotnet test parancsot. A dotnet test parancs mindkét projektet létrehozza, és futtatja a teszteket. Az xUnit tesztfuttató tartalmazza a tesztek futtatásához a program belépési pontát. dotnet test elindítja a tesztfuttatót az egységteszt-projekt használatával.

A teszt meghiúsul, mert IsPrime még nincs implementálva. A TDD-módszer használatával csak annyi kódot írjon, hogy a teszt sikeres legyen. Frissítse IsPrime a következő kóddal:

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

Futtassa a dotnet test programot. A teszt sikeres.

További tesztek hozzáadása

Adjon hozzá prímszámteszteket a 0 és a -1 számhoz. Másolhatja az előző lépésben létrehozott tesztet, és másolatot készíthet a következő kódról a 0 és a -1 teszteléséhez. De ne csináld, mert van egy jobb módszer.

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

Assert.False(result, "1 shouldn't be prime");

A tesztkód másolása, ha csak egy paraméter változása eredményez kódismétlést és tesztblobot. A következő xUnit-attribútumok lehetővé teszik egy hasonló tesztcsomag írását:

  • [Theory] olyan tesztcsomagot jelöl, amely ugyanazt a kódot hajtja végre, de különböző bemeneti argumentumokkal rendelkezik.
  • [InlineData] attribútum a bemenetek értékeit határozza meg.

Új tesztek létrehozása helyett alkalmazza az előző xUnit-attribútumokat egyetlen elmélet létrehozására. Cserélje le a következő kódot...

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

    Assert.False(result, "1 shouldn't be prime");
}

... a következő kóddal:

[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");
}

Az előző kódban [Theory] és [InlineData] lehetővé teszik a kétnél kisebb értékek tesztelését. A kettő a legkisebb prímszám.

Adja hozzá a következő kódot az osztály deklarációja után és az [Theory] attribútum előtt:

private readonly PrimeService _primeService;

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

Futtasd dotnet test, és két teszt megbukik. Az összes teszt sikeres végrehajtásához frissítse a metódust IsPrime a következő kóddal:

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

A TDD-megközelítést követve adjon hozzá további sikertelen teszteket, majd frissítse a célkódot. Tekintse meg a tesztek kész verzióját és a kódtár teljes implementációját.

A kész IsPrime metódus nem hatékony algoritmus az elsődlegesség teszteléséhez.

További erőforrások