Testowanie jednostkowe bibliotek platformy .NET Core języka Visual Basic przy użyciu narzędzia dotnet test i xUnit

W tym samouczku pokazano, jak utworzyć rozwiązanie zawierające projekt testowy jednostkowy i projekt biblioteki. Aby wykonać czynności opisane w samouczku przy użyciu wstępnie utworzonego rozwiązania, wyświetl lub pobierz przykładowy kod. Aby uzyskać instrukcje dotyczące pobierania, zobacz Przykłady i samouczki.

Tworzenie rozwiązania

W tej sekcji tworzone jest rozwiązanie zawierające projekty źródłowe i testowe. Ukończone rozwiązanie ma następującą strukturę katalogów:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.vb
        PrimeService.vbproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.vb
        PrimeServiceTests.vbproj

Poniższe instrukcje zawierają kroki tworzenia rozwiązania testowego. Zobacz Polecenia służące do tworzenia rozwiązania testowego, aby uzyskać instrukcje dotyczące tworzenia rozwiązania testowego w jednym kroku.

  • Otwórz okno powłoki.

  • Uruchom następujące polecenie:

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

    Polecenie dotnet new sln tworzy nowe rozwiązanie w katalogu unit-testing-using-dotnet-test .

  • Zmień katalog na folder unit-testing-using-dotnet-test .

  • Uruchom następujące polecenie:

    dotnet new classlib -o PrimeService --lang VB
    

    Polecenie dotnet new classlib tworzy nowy projekt biblioteki klas w folderze PrimeService . Nowa biblioteka klas będzie zawierać kod do przetestowania.

  • Zmień nazwę Class1.vb na PrimeService.vb.

  • Zastąp kod w PrimeService.vb następującym kodem:

    Imports System
    
    Namespace Prime.Services
        Public Class PrimeService
            Public Function IsPrime(candidate As Integer) As Boolean
                Throw New NotImplementedException("Not implemented.")
            End Function
        End Class
    End Namespace
    
  • Powyższy kod ma następujące działanie:

    • NotImplementedException Zgłasza komunikat z komunikatem wskazującym, że nie został zaimplementowany.
    • Zostanie zaktualizowany w dalszej części tego samouczka.
  • W katalogu unit-testing-using-dotnet-test uruchom następujące polecenie, aby dodać projekt biblioteki klas do rozwiązania:

    dotnet sln add ./PrimeService/PrimeService.vbproj
    
  • Utwórz projekt PrimeService.Tests, uruchamiając następujące polecenie:

    dotnet new xunit -o PrimeService.Tests
    
  • Poprzednie polecenie:

    • Tworzy projekt PrimeService.Tests w katalogu PrimeService.Tests. Projekt testowy używa narzędzia xUnit jako biblioteki testowej.
    • Konfiguruje moduł uruchamiający testy przez dodanie następujących <PackageReference />elementów do pliku projektu:
      • "Microsoft.NET.Test.Sdk"
      • "xunit"
      • "xunit.runner.visualstudio"
  • Dodaj projekt testowy do pliku rozwiązania, uruchamiając następujące polecenie:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.vbproj
    
  • Dodaj bibliotekę PrimeService klas jako zależność do projektu PrimeService.Tests :

    dotnet add ./PrimeService.Tests/PrimeService.Tests.vbproj reference ./PrimeService/PrimeService.vbproj  
    

Polecenia umożliwiające utworzenie rozwiązania

Ta sekcja zawiera podsumowanie wszystkich poleceń w poprzedniej sekcji. Pomiń tę sekcję, jeśli wykonano kroki opisane w poprzedniej sekcji.

Następujące polecenia umożliwiają utworzenie rozwiązania testowego na maszynie z systemem Windows. W przypadku systemów macOS i Unix zaktualizuj ren polecenie do wersji ren systemu operacyjnego, aby zmienić nazwę pliku:

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

Postępuj zgodnie z instrukcjami dotyczącymi funkcji "Zastąp kod w PrimeService.vb następującym kodem" w poprzedniej sekcji.

Tworzenie testu

Popularnym podejściem w procesie programowania opartego na testach (TDD) jest napisanie testu przed zaimplementowaniem kodu docelowego. W tym samouczku jest używane podejście TDD. Metoda IsPrime jest wywoływana, ale nie zaimplementowana. Wywołanie testowe kończy się niepowodzeniem IsPrime . W przypadku TDD test jest napisany, który jest znany jako niepowodzenie. Kod docelowy jest aktualizowany w celu wykonania testu. Powtarzasz to podejście, pisząc test kończący się niepowodzeniem, a następnie aktualizując kod docelowy do przekazania.

Zaktualizuj projekt PrimeService.Tests:

  • Usuń plik PrimeService.Tests/UnitTest1.vb.
  • Utwórz plik PrimeService.Tests/PrimeService_IsPrimeShould.vb.
  • Zastąp kod w PrimeService_IsPrimeShould.vb następującym kodem:
Imports Xunit

Namespace PrimeService.Tests
    Public Class PrimeService_IsPrimeShould
        Private ReadOnly _primeService As Prime.Services.PrimeService

        Public Sub New()
            _primeService = New Prime.Services.PrimeService()
        End Sub


        <Fact>
        Sub IsPrime_InputIs1_ReturnFalse()
            Dim result As Boolean = _primeService.IsPrime(1)

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

    End Class
End Namespace

Atrybut [Fact] deklaruje metodę testową uruchamianą przez moduł uruchamiający testy. W folderze PrimeService.Tests uruchom polecenie dotnet test. Polecenie dotnet test kompiluje zarówno projekty, jak i uruchamia testy. Moduł uruchamiający testy xUnit zawiera punkt wejścia programu w celu uruchomienia testów. dotnet test uruchamia moduł uruchamiający testy przy użyciu projektu testów jednostkowych.

Test kończy się niepowodzeniem, ponieważ IsPrime nie został zaimplementowany. Korzystając z podejścia TDD, napisz tylko wystarczająco dużo kodu, aby ten test przebiegł pomyślnie. Zaktualizuj IsPrime za pomocą następującego kodu:

Public Function IsPrime(candidate As Integer) As Boolean
    If candidate = 1 Then
        Return False
    End If
    Throw New NotImplementedException("Not implemented.")
End Function

Uruchom program dotnet test. Test zakończy się pomyślnie.

Dodawanie kolejnych testów

Dodaj testy liczb pierwszych dla 0 i -1. Możesz skopiować poprzedni test i zmienić następujący kod, aby użyć 0 i -1:

Dim result As Boolean = _primeService.IsPrime(1)

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

Kopiowanie kodu testowego, gdy tylko parametr zmienia się, powoduje duplikowanie kodu i przeloowanie testowe. Następujące atrybuty xUnit umożliwiają pisanie zestawu podobnych testów:

  • [Theory] reprezentuje zestaw testów, które wykonują ten sam kod, ale mają różne argumenty wejściowe.
  • [InlineData] atrybut określa wartości dla tych danych wejściowych.

Zamiast tworzyć nowe testy, zastosuj poprzednie atrybuty xUnit, aby utworzyć jedną teorię. Zastąp następujący kod:

<Fact>
Sub IsPrime_InputIs1_ReturnFalse()
    Dim result As Boolean = _primeService.IsPrime(1)

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

z następującym kodem:

<Theory>
<InlineData(-1)>
<InlineData(0)>
<InlineData(1)>
Sub IsPrime_ValuesLessThan2_ReturnFalse(ByVal value As Integer)
    Dim result As Boolean = _primeService.IsPrime(value)

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

W poprzednim kodzie [Theory] i [InlineData] włącz testowanie kilku wartości mniejszych niż dwa. Dwa to najmniejsza liczba główna.

Uruchom polecenie dotnet test, dwa testy kończą się niepowodzeniem. Aby wszystkie testy przeszły, zaktualizuj metodę IsPrime przy użyciu następującego kodu:

Public Function IsPrime(candidate As Integer) As Boolean
    If candidate < 2 Then
        Return False
    End If
    Throw New NotImplementedException("Not fully implemented.")
End Function

Zgodnie z podejściem TDD dodaj więcej testów zakończonych niepowodzeniem, a następnie zaktualizuj kod docelowy. Zobacz ukończoną wersję testów i pełną implementację biblioteki.

Ukończona IsPrime metoda nie jest wydajnym algorytmem testowania pierwotnego.

Dodatkowe zasoby