Dotnet test ve xUnit kullanarak .NET Core'da C# birim testi

Bu öğreticide, birim testi projesi ve kaynak kodu projesi içeren bir çözümün nasıl derlemesi gerekir? Önceden yerleşik bir çözüm kullanarak öğreticiyi takip etmek için örnek kodu indirebilirsiniz. İndirme yönergeleri için bkz. Örnekler ve Öğreticiler.

Çözümü oluşturma

Bu bölümde, kaynak ve test projelerini içeren bir çözüm oluşturulur. Tamamlanan çözüm aşağıdaki dizin yapısına sahiptir:

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

Aşağıdaki yönergeler, test çözümünü oluşturma adımlarını sağlar. Test çözümünü tek adımda oluşturma yönergeleri için bkz. Test çözümü oluşturma komutları.

  • Bir kabuk penceresi açın.

  • Şu komutu çalıştırın:

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

    komutu dotnet new sln unit-testing-using-dotnet-test dizininde yeni bir çözüm oluşturur.

  • dizini unit-testing-using-dotnet-test klasörüne gidin.

  • Şu komutu çalıştırın:

    dotnet new classlib -o PrimeService
    

    komutu dotnet new classlib PrimeService klasöründe yeni bir sınıf kitaplığı projesi oluşturur. Yeni sınıf kitaplığı test edilecek kodu içerir.

  • Class1.cs'yi PrimeService.cs olarak yeniden adlandır.

  • PrimeService.cs'de kodu aşağıdaki kodla değiştirin:

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

    • Uygulanmadığını NotImplementedException belirten bir iletiyle birlikte atar.
    • Öğreticinin devamlarında güncelleştirilir.
  • Unit-testing-using-dotnet-test dizininde, sınıf kitaplığı projesini çözüme eklemek için aşağıdaki komutu çalıştırın:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Aşağıdaki komutu çalıştırarak PrimeService.Tests projesini oluşturun:

    dotnet new xunit -o PrimeService.Tests
    
  • Yukarıdaki komut:

    • PrimeService.Tests dizininde PrimeService.Tests projesini oluşturur. Test projesi, test kitaplığı olarak xUnit kullanır.
    • Proje dosyasına aşağıdaki öğeleri ekleyerek test <PackageReference /> çalıştırıcıyı yapılandırır:
      • Microsoft.NET.Test.Sdk
      • xunit
      • xunit.runner.visualstudio
      • coverlet.collector
  • Aşağıdaki komutu çalıştırarak test projesini çözüm dosyasına ekleyin:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Sınıf PrimeService kitaplığını PrimeService.Tests projesine bağımlılık olarak ekleyin:

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

Çözümü oluşturma komutları

Bu bölümde önceki bölümde yer alan tüm komutlar özetlenmiştir. Önceki bölümdeki adımları tamamladıysanız bu bölümü atlayabilirsiniz.

Aşağıdaki komutlar bir Windows makinesi üzerinde test çözümünü oluştur. macOS ve Unix için, bir dosyayı yeniden adlandırmak için komutunu ren işletim ren sistemi sürümüne güncelleştirin:

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

Önceki bölümde yer alan "PrimeService.cs'de kodu aşağıdaki kodla değiştirin" yönergelerini izleyin.

Test oluşturma

Test odaklı geliştirmede (TDD) popüler bir yaklaşım, hedef kodu uygulamadan önce bir test yazmaktır. Bu öğreticide TDD yaklaşımı 2. IsPrimeyöntemi çağrılabilir ancak uygulanmaz. için test çağrısı başarısız IsPrime oluyor. TDD ile başarısız olduğu bilinen bir test yazılır. Hedef kod, test geçişini yapacak şekilde güncelleştirilir. Bu yaklaşımı yinelemeye devam ediyor, başarısız bir test yazıyor ve ardından geçiş için hedef kodu güncelleştiriyor.

PrimeService.Tests projesini güncelleştirin:

  • PrimeService.Tests/UnitTest1.cs'yi silin.
  • PrimeService.Tests/PrimeService_IsPrimeShould.cs dosyası oluşturun.
  • PrimeService_IsPrimeShould.cs'de kodu aşağıdaki kodla değiştirin:
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");
        }
    }
}

özniteliği, [Fact] test çalıştırıcısı tarafından çalıştıracak bir test yöntemi bildirer. PrimeService.Tests klasöründen dotnet test çalıştırın. dotnet test komutu her iki projeyi de derlemek ve testleri çalıştırır. xUnit test çalıştırıcısı, testleri çalıştırmak için program giriş noktasını içerir. dotnet test birim testi projesini kullanarak test çalıştırıcıyı başlatır.

Uygulanmamış olduğundan test IsPrime başarısız olur. TDD yaklaşımını kullanarak yalnızca bu testin başarılı olduğu yeterli kodu yazın. aşağıdaki IsPrime kodla güncelleştirin:

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

dotnet test öğesini çalıştırın. Test başarılı olur.

Daha fazla test ekleme

0 ve -1 için asal sayı testleri ekleyin. Önceki adımda oluşturulan testi kopyalayıp 0 ve -1 testlerini yapmak için aşağıdaki kodun kopyalarını edinebilirsiniz. Ancak daha iyi bir yol olduğu için bunu yapma.

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

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

Yalnızca bir parametre değişirken test kodunun kopya yapılması, kod yinelemesi ve testbloat ile sonuç verir. Aşağıdaki xUnit öznitelikleri, benzer testlerden oluşan bir paket yazmaya olanak sağlar:

  • [Theory] , aynı kodu yürüten ancak farklı giriş bağımsız değişkenleri olan bir test paketini temsil eder.
  • [InlineData] özniteliği, bu girişler için değerleri belirtir.

Yeni testler oluşturmak yerine, tek bir teori oluşturmak için önceki xUnit özniteliklerini kullanın. Aşağıdaki kodu değiştirin:

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

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

aşağıdaki kodla:

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

Yukarıdaki kodda ve [Theory] [InlineData] ikiden küçük birkaç değeri test etme özelliğine olanak sağlar. İki, en küçük asal sayıdır.

Sınıf bildiriminin ardından ve özniteliğinin öncesini aşağıdaki kodu [Theory] ekleyin:

private readonly PrimeService _primeService;

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

çalıştırın dotnet test ve testlerden ikisi başarısız olur. Tüm testleri başarılı yapmak için yöntemini IsPrime aşağıdaki kodla güncelleştirin:

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

TDD yaklaşımını kullanarak daha fazla başarısız test ekleyin ve hedef kodu güncelleştirin. Testlerin son sürümüne ve kitaplığının tam uygulamasına bakın.

Tamamlanan IsPrime yöntem, ilkelliği test etmek için verimli bir algoritma değildir.

Ek kaynaklar