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

本教程逐步讲解了构建示例解决方案的交互式体验,以学习单元测试概念。 如果希望使用预构建解决方案学习本教程,请在开始前查看或下载示例代码。 有关下载说明,请参阅 示例和教程

本文介绍如何测试 .NET Core 项目。 如果要测试 ASP.NET Core 项目,请参阅 ASP.NET Core中的 集成测试。

先决条件

  • .NET 8 SDK 或更高版本。
  • 你选择的文本编辑器或代码编辑器。

创建源项目

打开 shell 窗口。 创建名为 unit-testing-vb-nunit 的目录来保存解决方案。 在此新目录中,运行以下命令,为类库和测试项目创建新的解决方案文件:

dotnet new sln

接下来,创建 PrimeService 目录。 以下大纲显示到目前为止的文件结构:

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService

PrimeService 设为当前目录并运行以下命令以创建源项目:

dotnet new classlib -lang VB

Class1.VB 重命名为 PrimeService.VB。 创建 PrimeService 类的失败实现:

Namespace Prime.Services
    Public Class PrimeService
        Public Function IsPrime(candidate As Integer) As Boolean
            Throw New NotImplementedException("Please create a test first.")
        End Function
    End Class
End Namespace

将目录更改回 unit-testing-vb-using-mstest 目录。 运行以下命令,将类库项目添加到解决方案:

dotnet sln add .\PrimeService\PrimeService.vbproj

创建测试项目

接下来,创建 PrimeService.Tests 目录。 以下大纲显示了目录结构:

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService
        Source Files
        PrimeService.vbproj
    /PrimeService.Tests

PrimeService.Tests 目录设为当前目录,并使用以下命令创建新项目:

dotnet new nunit -lang VB

dotnet new 命令创建一个使用 NUnit 作为测试库的测试项目。 生成的模板在 PrimeServiceTests.vbproj 文件中配置测试运行程序:

<ItemGroup>
  <PackageReference Include="nunit" Version="4.3.2" />
  <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
</ItemGroup>

注释

在 .NET 9 之前,生成的代码可以引用较旧版本的 NUnit 测试框架。 可以使用 dotnet CLI 更新包。 或者,打开 PrimeService.Tests.vbproj 文件,并将包引用项组的内容替换为上面的代码。

测试项目需要其他包来创建和运行单元测试。 dotnet new 在上一步骤中添加了 NUnit 和 NUnit 测试适配器。 现在,将 PrimeService 类库添加为项目的另一个依赖项。 使用 dotnet reference add 命令:

dotnet reference add ../PrimeService/PrimeService.vbproj

可以在 GitHub 上的 示例存储库 中看到整个文件。

你有以下最终解决方案布局:

/unit-testing-vb-nunit
    unit-testing-vb-nunit.sln
    /PrimeService
        Source Files
        PrimeService.vbproj
    /PrimeService.Tests
        Test Source Files
        PrimeService.Tests.vbproj

unit-testing-vb-nunit 目录中执行以下命令:

dotnet sln add .\PrimeService.Tests\PrimeService.Tests.vbproj

创建第一个测试

编写一个失败测试,使其通过,然后重复此过程。 在 PrimeService.Tests 目录中,将 UnitTest1.vb 文件重命名为 PrimeService_IsPrimeShould.VB ,并将其整个内容替换为以下代码:

Imports NUnit.Framework

Namespace PrimeService.Tests
    <TestFixture>
    Public Class PrimeService_IsPrimeShould
        Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

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

            Assert.That(result, [Is].False, $"1 should not be prime")
        End Sub

    End Class
End Namespace

<TestFixture> 属性指示包含测试的类。 <Test> 属性表示由测试运行程序运行的方法。 在 unit-testing-vb-nunit 中,执行 dotnet test 以生成测试和类库,然后运行测试。 NUnit 测试运行程序包含用于运行测试的程序入口点。 dotnet test 使用已创建的单元测试项目启动测试运行程序。

测试失败。 尚未创建实现。 在起作用的 PrimeService 类中编写最简单的代码,使此测试通过:

Public Function IsPrime(candidate As Integer) As Boolean
    If candidate = 1 Then
        Return False
    End If
    Throw New NotImplementedException("Please create a test first.")
End Function

unit-testing-vb-nunit 目录中,再次运行 dotnet testdotnet test 命令构建 PrimeService 项目,然后构建 PrimeService.Tests 项目。 生成这两个项目后,它将运行此单个测试。 测试通过。

添加更多功能

你已经通过了一个测试,现在可以编写更多测试。 质数有其他几种简单情况:0,-1。 可以将这些事例添加为具有 <Test> 属性的新测试,但这很快变得繁琐。 还有其他 xUnit 属性可用于编写一套类似的测试。 属性 <TestCase> 表示执行相同代码但具有不同输入参数的测试套件。 可以使用特性 <TestCase> 为这些输入指定值。

与其创建新的测试,请应用这两个属性以创建一系列测试,测试几个小于 2 的值,2 是最小的质数。

<TestFixture>
Public Class PrimeService_IsPrimeShould
    Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

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

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

    <TestCase(2)>
    <TestCase(3)>
    <TestCase(5)>
    <TestCase(7)>
    Public Sub IsPrime_PrimesLessThan10_ReturnTrue(value As Integer)
        Dim result As Boolean = _primeService.IsPrime(value)

        Assert.That(result, [Is].True, $"{value} should be prime")
    End Sub

    <TestCase(4)>
    <TestCase(6)>
    <TestCase(8)>
    <TestCase(9)>
    Public Sub IsPrime_NonPrimesLessThan10_ReturnFalse(value As Integer)
        Dim result As Boolean = _primeService.IsPrime(value)

        Assert.That(result, [Is].False, $"{value} should not be prime")
    End Sub
End Class

运行 dotnet test,两项测试均失败。 若要使所有测试通过,请更改if文件中的Main方法开头的子句。

if candidate < 2

继续通过在主库中添加测试、理论和代码来进行迭代。 你将拥有已完成的测试版本库的完整实现

你已为该库生成了一个小库和一组单元测试。 你已构建解决方案,以便添加新包和测试是正常工作流的一部分。 你大部分时间都专注于解决应用程序的目标。