Поделиться через


Модульное тестирование библиотек Visual Basic .NET Core с помощью dotnet test и xUnit

В этом руководстве показано, как создать решение, содержащее проект модульного теста и проект библиотеки. Чтобы выполнить руководство с помощью предварительно созданного решения, просмотрите или скачайте пример кода. Инструкции по скачиванию смотрите в разделах Образцы и руководства.

Создание решения

В этом разделе создается решение, содержащее исходные и тестовые проекты. Готовое решение имеет следующую структуру каталогов:

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

Ниже приведены инструкции по созданию тестового решения. Команды для создания тестового решения, чтобы сделать это в один шаг.

  • Откройте окно оболочки.

  • Выполните следующую команду:

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

    Команда dotnet new sln создает новое решение в каталоге unit-testing-using-dotnet-test .

  • Измените каталог на папку unit-testing-using-dotnet-test .

  • Выполните следующую команду:

    dotnet new classlib -o PrimeService -lang VB
    

    Команда dotnet new classlib создает проект библиотеки классов в папке PrimeService . Новая библиотека классов будет содержать тестируемый код.

  • Переименуйте Class1.vb в PrimeService.vb.

  • Замените код в PrimeService.vb следующим кодом:

    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
    
  • Предыдущий код:

    • Выбрасывает NotImplementedException с сообщением, указывающим, что это не реализовано.
    • Обновляется позже в руководстве.
  • В каталоге unit-testing-using-dotnet-test выполните следующую команду, чтобы добавить проект библиотеки классов в решение:

    dotnet sln add ./PrimeService/PrimeService.vbproj
    
  • Создайте проект PrimeService.Tests , выполнив следующую команду:

    dotnet new xunit -o PrimeService.Tests -lang VB
    
  • Предыдущая команда:

    • Создает проект PrimeService.Tests в каталоге PrimeService.Tests . Тестовый проект использует xUnit в качестве тестовой библиотеки.
    • Настраивает средство выполнения теста, добавив следующие <PackageReference />элементы в файл проекта:
      • "Microsoft.NET.Test.Sdk"
      • "xunit"
      • xunit.runner.visualstudio
  • Добавьте тестовый проект в файл решения, выполнив следующую команду:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.vbproj
    
  • Добавьте библиотеку PrimeService классов в качестве зависимости в проект PrimeService.Tests :

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

Команды для создания решения

В этом разделе перечислены все команды, описанные в предыдущем разделе. Пропустите этот раздел, если вы выполнили действия, описанные в предыдущем разделе.

Следующие команды создают тестовое решение на компьютере Windows. Для macOS и Unix обновите ren команду до версии ren ОС, чтобы переименовать файл:

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 -lang VB
dotnet add ./PrimeService.Tests/PrimeService.Tests.vbproj reference ./PrimeService/PrimeService.vbproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.vbproj

Выполните инструкции по замене кода в PrimeService.vb следующим кодом в предыдущем разделе.

Создайте тест

Популярный подход к разработке на основе тестов (TDD) заключается в написании теста перед реализацией целевого кода. В этом руководстве используется подход TDD. Метод IsPrime вызывается, но не реализуется. Сбой тестового вызова IsPrime . При использовании TDD пишется тест, который заведомо не будет пройден. Целевой код обновляется, чтобы пройти тестовый проход. Вы продолжаете повторять этот подход: пишете провалившийся тест, а затем обновляете целевой код, чтобы он прошел.

Обновите проект PrimeService.Tests :

  • Удаление PrimeService.Tests/UnitTest1.vb.
  • Создайте файл PrimeService.Tests/PrimeService_IsPrimeShould.vb .
  • Замените код в PrimeService_IsPrimeShould.vb следующим кодом:
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

Атрибут [Fact] объявляет метод тестирования, который выполняется тестовым раннером. В папке PrimeService.Tests выполните команду dotnet test. Команда dotnet test создает оба проекта и запускает тесты. Запускатель тестов xUnit содержит точку входа программы для выполнения тестов. dotnet test запускает средство выполнения теста с помощью проекта модульного теста.

Тест завершается ошибкой, так как IsPrime не был реализован. Используя подход TDD, напишите только достаточно кода, чтобы этот тест прошел. Обновите IsPrime, включив в него следующий код.

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

Выполните dotnet test. Тест пройден.

Добавьте дополнительные тесты.

Добавьте тесты праймерных чисел для 0 и -1. Вы можете скопировать предыдущий тест и изменить следующий код, чтобы использовать 0 и -1:

Dim result As Boolean = _primeService.IsPrime(1)

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

Копирование тестового кода, когда изменяется только один параметр, приводит к дублированию кода и разрастанию тестов. Следующие атрибуты xUnit позволяют создавать набор аналогичных тестов:

  • [Theory] представляет набор тестов, которые выполняют один и тот же код, но имеют разные входные аргументы.
  • [InlineData] атрибут задает значения для этих входных данных.

Вместо создания новых тестов примените предыдущие атрибуты xUnit для создания одной теории. Замените следующий код:

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

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

указанным ниже кодом:

<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

В приведенном выше коде [Theory] и [InlineData] включите тестирование нескольких значений менее двух. Два — наименьшее первое число.

При выполнении dotnet test, два теста завершаются сбоем. Чтобы выполнить все тесты, обновите IsPrime метод следующим кодом:

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

После подхода TDD добавьте более неудачные тесты, а затем обновите целевой код. Ознакомьтесь с готовой версией тестов и полной реализацией библиотеки.

Завершенный IsPrime метод не является эффективным алгоритмом для тестирования примиальности.

Дополнительные ресурсы