Pengujian unit C# di .NET menggunakan uji dotnet dan xUnit

Tutorial ini menunjukkan cara membangun solusi yang berisi proyek pengujian unit dan proyek kode sumber. Untuk mengikuti tutorial menggunakan solusi bawaan, lihat atau unduh kode sampel. Untuk petunjuk pengunduhan, lihat Sampel dan Tutorial.

Buat solusinya

Di bagian ini, solusi dibuat yang berisi proyek sumber dan pengujian. Solusi yang telah selesai memiliki struktur direktori berikut:

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

Instruksi berikut menyediakan langkah-langkah untuk membuat solusi pengujian. Lihat Perintah untuk membuat solusi pengujian untuk instruksi membuat solusi pengujian dalam satu langkah.

  • Buka jendela shell.

  • Jalankan perintah berikut:

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

    Perintah dotnet new sln membuat solusi baru di direktori unit-testing-using-dotnet-test .

  • Ubah direktori ke folder unit-testing-using-dotnet-test .

  • Jalankan perintah berikut:

    dotnet new classlib -o PrimeService
    

    dotnet new classlib Perintah membuat proyek pustaka kelas baru di folder PrimeService. Pustaka kelas baru akan berisi kode yang akan diuji.

  • Ganti nama Class1.cs menjadi PrimeService.cs.

  • Ganti kode di PrimeService.cs dengan kode berikut:

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

    • Melempar dengan NotImplementedException pesan yang menunjukkan bahwa pesan tidak diimplementasikan.
    • Diperbarui nanti dalam tutorial.
  • Di direktori unit-testing-using-dotnet-test, jalankan perintah berikut untuk menambahkan proyek pustaka kelas ke solusi:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Buat proyek PrimeService.Tests dengan menjalankan perintah berikut:

    dotnet new xunit -o PrimeService.Tests
    
  • Perintah sebelumnya:

    • Membuat proyek PrimeService.Tests di direktori PrimeService.Tests. Proyek pengujian menggunakan xUnit sebagai pustaka pengujian.
    • Mengonfigurasi runner pengujian dengan menambahkan elemen berikut <PackageReference />ke file proyek:
      • Microsoft.NET.Test.Sdk
      • xunit
      • xunit.runner.visualstudio
      • coverlet.collector
  • Tambahkan proyek pengujian ke file solusi dengan menjalankan perintah berikut:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • PrimeService Tambahkan pustaka kelas sebagai dependensi ke proyek PrimeService.Tests:

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

Perintah untuk membuat solusi

Bagian ini meringkas semua perintah di bagian sebelumnya. Lewati bagian ini jika Anda telah menyelesaikan langkah-langkah di bagian sebelumnya.

Perintah berikut membuat solusi pengujian pada komputer Windows. Untuk macOS dan Unix, perbarui ren perintah ke versi ren OS untuk mengganti nama file:

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

Ikuti instruksi untuk "Ganti kode di PrimeService.cs dengan kode berikut" di bagian sebelumnya.

Membuat pengujian

Pendekatan populer dalam pengembangan berbasis pengujian (TDD) adalah menulis pengujian (gagal) sebelum menerapkan kode target. Tutorial ini menggunakan pendekatan TDD. Metode IsPrime ini dapat dipanggil, tetapi tidak diimplementasikan. Panggilan uji gagal IsPrime . Dengan TDD, tes ditulis yang diketahui gagal. Kode target diperbarui untuk membuat lulus pengujian. Anda terus mengulangi pendekatan ini, menulis pengujian yang gagal dan kemudian memperbarui kode target untuk lulus.

Perbarui proyek PrimeService.Tests:

  • Hapus PrimeService.Tests/UnitTest1.cs.
  • Buat file PrimeService.Tests/PrimeService_IsPrimeShould.cs .
  • Ganti kode di PrimeService_IsPrimeShould.cs dengan kode berikut:
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");
        }
    }
}

Atribut [Fact] mendeklarasikan metode pengujian yang dijalankan oleh runner pengujian. Dari folder PrimeService.Tests , jalankan dotnet test. Perintah uji dotnet membangun proyek dan menjalankan pengujian. Runner uji xUnit berisi titik masuk program untuk menjalankan pengujian. dotnet test memulai runner pengujian menggunakan proyek pengujian unit.

Pengujian gagal karena IsPrime belum diimplementasikan. Dengan menggunakan pendekatan TDD, tulis kode yang cukup sehingga pengujian ini lolos. Perbarui IsPrime dengan kode berikut:

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

Jalankan dotnet test. Tes lolos.

Menambahkan lebih banyak pengujian

Tambahkan tes nomor primer untuk 0 dan -1. Anda dapat menyalin pengujian yang dibuat pada langkah sebelumnya dan membuat salinan kode berikut untuk menguji 0 dan -1. Tapi jangan lakukan, karena ada cara yang lebih baik.

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

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

Menyalin kode pengujian ketika hanya perubahan parameter yang menghasilkan duplikasi kode dan uji kembung. Atribut xUnit berikut memungkinkan penulisan serangkaian pengujian serupa:

  • [Theory] mewakili serangkaian pengujian yang menjalankan kode yang sama tetapi memiliki argumen input yang berbeda.
  • [InlineData] atribut menentukan nilai untuk input tersebut.

Daripada membuat pengujian baru, terapkan atribut xUnit sebelumnya untuk membuat satu teori. Ganti kode berikut:

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

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

dengan kode berikut:

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

Dalam kode sebelumnya, [Theory] dan [InlineData] aktifkan pengujian beberapa nilai kurang dari dua. Dua adalah angka utama terkecil.

Tambahkan kode berikut setelah deklarasi kelas dan sebelum [Theory] atribut :

private readonly PrimeService _primeService;

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

Jalankan dotnet test, dan dua pengujian gagal. Untuk membuat semua tes lulus, perbarui IsPrime metode dengan kode berikut:

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

Setelah pendekatan TDD, tambahkan lebih banyak pengujian yang gagal, lalu perbarui kode target. Lihat versi pengujian yang sudah selesai dan implementasi lengkap pustaka.

Metode yang diselesaikan IsPrime bukanlah algoritma yang efisien untuk menguji primalitas.

Sumber Daya Tambahan: