Dotnet test ve NUnit kullanarak F# kitaplıklarını birim testi

Bu öğreticide, birim testi kavramlarını öğrenmek için adım adım örnek bir çözüm oluşturma etkileşimli bir deneyime geçilir. Önceden oluşturulmuş bir çözüm kullanarak öğreticiyi izlemeyi tercih ediyorsanız başlamadan önce örnek kodu görüntüleyin veya indirin. İndirme yönergeleri için bkz . Örnekler ve öğreticiler.

Bu makale bir .NET Core projelerini test etme hakkındadır. ASP.NET Core projesini test ediyorsanız bkz . ASP.NET Core'da tümleştirme testleri.

Önkoşullar

  • .NET 8 SDK veya sonraki sürümleri.
  • Tercih ettiğiniz bir metin veya kod düzenleyicisi.

Kaynak projeyi oluşturma

Bir kabuk penceresi açın. Çözümü tutmak için unit-testing-with-fsharp adlı bir dizin oluşturun. Bu yeni dizinin içinde aşağıdaki komutu çalıştırarak sınıf kitaplığı ve test projesi için yeni bir çözüm dosyası oluşturun:

dotnet new sln

Ardından bir MathService dizini oluşturun. Şu ana hat, şu ana kadarki dizin ve dosya yapısını gösterir:

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService

MathService'i geçerli dizin yapın ve aşağıdaki komutu çalıştırarak kaynak projeyi oluşturun:

dotnet new classlib -lang "F#"

Matematik hizmetinin başarısız bir uygulamasını oluşturursunuz:

module MyMath =
    let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Dizini yeniden unit-testing-with-fsharp dizinine değiştirin. Çözüme sınıf kitaplığı projesini eklemek için aşağıdaki komutu çalıştırın:

dotnet sln add .\MathService\MathService.fsproj

Test projesini oluşturma

Ardından MathService.Tests dizinini oluşturun. Aşağıdaki ana hat dizin yapısını gösterir:

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests

MathService.Tests dizinini geçerli dizin yapın ve aşağıdaki komutu kullanarak yeni bir proje oluşturun:

dotnet new nunit -lang "F#"

Bu komut, test çerçevesi olarak NUnit kullanan bir test projesi oluşturur. Oluşturulan şablon MathServiceTests.fsproj dosyasında test çalıştırıcısını yapılandırıyor:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
  <PackageReference Include="NUnit" Version="4.1.0" />
  <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

Test projesi, birim testleri oluşturmak ve çalıştırmak için başka paketler gerektirir. dotnet new önceki adımda NUnit ve NUnit test bağdaştırıcısı eklendi. Şimdi, sınıf kitaplığını MathService projeye başka bir bağımlılık olarak ekleyin. dotnet add reference Komutunu kullanın:

dotnet add reference ../MathService/MathService.fsproj

Dosyanın tamamını GitHub'daki örnek deposunda görebilirsiniz.

Aşağıdaki son çözüm düzenine sahipsiniz:

/unit-testing-with-fsharp
    unit-testing-with-fsharp.sln
    /MathService
        Source Files
        MathService.fsproj
    /MathService.Tests
        Test Source Files
        MathService.Tests.fsproj

Unit-testing-with-fsharp dizininde aşağıdaki komutu yürütür:

dotnet sln add .\MathService.Tests\MathService.Tests.fsproj

İlk testi oluşturma

Başarısız bir test yazar, başarılı olur ve işlemi tekrarlarsınız. UnitTest1.fs dosyasını açın ve aşağıdaki kodu ekleyin:

namespace MathService.Tests

open System
open NUnit.Framework
open MathService

[<TestFixture>]
type TestClass () =

    [<Test>]
    member this.TestMethodPassing() =
        Assert.That(true, Is.True)

    [<Test>]
     member this.FailEveryTime() = Assert.That(false, Is.True)

özniteliği, [<TestFixture>] testleri içeren bir sınıfı belirtir. özniteliği, [<Test>] test çalıştırıcısı tarafından çalıştırılan bir test yöntemini belirtir. Unit-testing-with-fsharp dizininden testleri dotnet test ve sınıf kitaplığını derlemek ve ardından testleri çalıştırmak için komutunu yürütür. NUnit test çalıştırıcısı, testlerinizi çalıştırmak için program giriş noktasını içerir. dotnet test oluşturduğunuz birim testi projesini kullanarak test çalıştırıcısını başlatır.

Bu iki test en temel geçiş ve başarısız testleri gösterir. My test geçer ve Fail every time başarısız olur. Şimdi yöntemi için squaresOfOdds bir test oluşturun. yöntemi, squaresOfOdds giriş dizisinin parçası olan tüm tek tamsayı değerlerinin karelerinin bir dizisini döndürür. Bu işlevlerin tümünü aynı anda yazmaya çalışmak yerine, işlevselliği doğrulayan testleri yinelemeli olarak oluşturabilirsiniz. Her test geçişinin ortalamasını yapmak için yöntemi için gerekli işlevselliği oluşturursunuz.

Yazabileceğiniz en basit test, sonucun boş bir tamsayı dizisi olması gereken tüm çift sayılarla çağırmaktır squaresOfOdds . Bu test şu şekildedir:

[<Test>]
member this.TestEvenSequence() =
    let expected = Seq.empty<int>
    let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
    Assert.That(actual, Is.EqualTo(expected))

Sıranın expected listeye dönüştürüldüğüne dikkat edin. NUnit çerçevesi birçok standart .NET türüne dayanır. Bu bağımlılık, ortak arabiriminizin ve beklenen sonuçların yerine IEnumerabledestek ICollection olduğu anlamına gelir.

Testi çalıştırdığınızda, testinizin başarısız olduğunu görürsünüz. Bunun nedeni, uygulamayı henüz oluşturmamış olmanızdır. MathService projenizdeki library.fs sınıfında çalışan en basit kodu yazarak bu testi geçirin:

let squaresOfOdds xs =
    Seq.empty<int>

Unit-testing-with-fsharp dizininde yeniden çalıştırındotnet test. komutu, dotnet test proje için MathService ve ardından proje için MathService.Tests bir derleme çalıştırır. Her iki proje de derledikten sonra testlerinizi çalıştırır. İki test geçti.

Gereksinimleri tamamlama

Artık bir test geçişi yaptığınıza göre, daha fazla yazmanın zamanı geldi. Sonraki basit durum, tek sayı 1olan bir diziyle çalışır. 1 sayısı daha kolaydır çünkü 1'in karesi 1'dir. Sonraki test şu şekildedir:

[<Test>]
member public this.TestOnesAndEvens() =
    let expected = [1; 1; 1; 1]
    let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
    Assert.That(actual, Is.EqualTo(expected))

dotnet test Yürütme işlemi yeni testte başarısız oluyor. Bu yeni testi işlemek için yöntemini güncelleştirmeniz squaresOfOdds gerekir. Bu testin başarılı olması için çift sayıların tümünü sıralama dışında filtrelemeniz gerekir. Bunu yapmak için küçük bir filtre işlevi yazıp komutunu kullanabilirsiniz Seq.filter:

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd

Atacak bir adım daha var: tek sayıların her birini karekökle. Yeni bir test yazarak başlayın:

[<Test>]
member public this.TestSquaresOfOdds() =
    let expected = [1; 9; 25; 49; 81]
    let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
    Assert.That(actual, Is.EqualTo(expected))

Her bir tek sayının karesini hesaplamak için bir eşleme işlemi aracılığıyla filtrelenmiş diziyi borulayarak testi düzeltebilirsiniz:

let private square x = x * x
let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
    xs
    |> Seq.filter isOdd
    |> Seq.map square

Bu kitaplık için küçük bir kitaplık ve bir dizi birim testi oluşturdunuz. Çözümü, yeni paketlerin ve testlerin eklenmesinin normal iş akışının bir parçası olması için yapılandırmışsınız. Zamanınızın ve çabanızın çoğunu uygulamanın hedeflerini çözmeye yoğunlaştırmıştınız.

Ayrıca bkz.