使用 dotnet test 和 xUnit 对 Visual Basic .NET Core 库进行单元测试

本教程演示如何生成包含单元测试项目和库项目的解决方案。 若要使用预构建的解决方案按照教程进行作, 请查看或下载示例代码。 有关下载说明,请参阅 示例和教程

创建解决方案

在本部分中,将创建一个包含源和测试项目的解决方案。 已完成的解决方案具有以下目录结构:

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

以下说明提供了创建测试解决方案的步骤。 有关在一个步骤中创建测试解决方案的说明,请参阅 命令以创建 测试解决方案。

  • 打开 shell 窗口。

  • 运行下面的命令:

    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
    
  • 前面的代码:

  • 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 命令更新为 OS 版本 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 testdotnet 测试命令生成项目并运行测试。 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 方法不是用于测试素性的有效算法。

其他资源