Asp.Net 中的单元测试:完整教程

⚡ 智能摘要

在 Visual Studio 中对 ASP.NET 应用程序进行单元测试,首先创建一个单元测试项目,然后连接对目标项目的引用,添加 MSTest [TestClass] 和 [TestMethod] 特性,并调用 Assert 方法来验证类是否按设计运行。

  • 🧪 测试项目: 在 ASP.NET 解决方案中添加单元测试项目,并引用要验证的目标项目。
  • 🏷️ 属性: 使用 [TestClass] 标记类,使用 [TestMethod] 标记每个测试,以便 MSTest 可以发现它们。
  • 断言: 使用 Assert.AreEqual、Assert.IsTrue 和类似调用来声明每个测试的预期结果。
  • ▶️ 运行测试: 在 Visual Studio 中执行“测试”菜单,运行所有测试,并在测试资源管理器中检查通过和失败的结果。
  • 框架选择: MSTest、NUnit 和 xUnit 都适用于 dotnet test;MSTest 默认随附,xUnit 是 ASP.NET Core 的首选。
  • 🛠️ 最佳实践: 隔离单元,遵循 Arrange Act Assert 的原则,并保持整个套件运行速度快,以便在每次提交时都能运行。

ASP.NET 中的单元测试

测试是任何编程语言的一个重要方面。 测试与验证 借助 Visual Studio,可以实现 ASP.NET 应用程序的开发。

Visual Studio 用于创建测试代码,也用于运行 ASP.NET 应用程序的测试代码。这样,检查 ASP.NET 应用程序中的任何错误就变得非常简单。Visual Studio 内置了测试模块,功能齐全,可以直接对 ASP.NET 项目执行测试。

ASP.NET 测试简介

ASP.NET 项目测试的第一层是单元测试。单元测试主要针对应用程序的功能。测试的目的是确保应用程序的行为符合预期。在 ASP.NET 中,首要任务是在 Visual Studio 中创建一个测试项目。该测试项目将包含测试应用程序所需的全部代码。

让我们来看下面的网页。网页中包含以下信息:“Guru屏幕上显示“99 – ASP.NET”。现在,我们如何确认在 ASP.NET 项目运行时显示的是正确的消息呢?这可以通过向 ASP.NET 解决方案(用于开发 Web 应用程序)添加一个测试项目来实现。该测试项目将确保向用户显示正确的消息。

ASP.NET 测试简介

现在让我们更详细地了解一下如何在 ASP.NET 中进行测试。

创建 .NET 单元测试项目

在创建测试项目之前,我们需要执行以下高级步骤。

  1. 使用前面部分中使用的“DemoApplication”。这将是我们需要测试的应用程序。
  2. 我们将向 DemoApplication 添加一个新类。此类将包含一个名为“Guru99 – ASP.NET。'此字符串将在我们的测试项目中进行测试。
  3. 最后,我们将创建一个测试项目。该项目用于测试 ASP.NET 应用程序。

那么,让我们按照上述高级步骤来看看如何实现测试。

步骤1) 确保 DemoApplication 在 Visual Studio 中打开。

步骤2) 现在让我们向 DemoApplication 添加一个新类。此类将包含一个名为“Guru99 – ASP.NET。'此字符串将在我们的测试项目中进行测试。

按照以下步骤添加新课程。

创建 .NET 单元测试项目

  1. 在 Visual Studio 中,右键单击解决方案资源管理器中的“DemoApplication”。
  2. 从上下文菜单中选择选项添加->类。

步骤3) 在此步骤中,

创建 .NET 单元测试项目

  1. 为新类命名“Tutorial.cs”。
  2. 单击“添加”按钮将文件添加到 DemoApplication。

现在,一个新类被添加到文件“DemoApplication”中。

步骤4) 打开“DemoApplication”中的新 Tutorial.cs 文件。添加字符串“Guru99 – ASP.NET。”

要打开该文件,请双击解决方案资源管理器中的 Tutorial.cs 文件。

创建 .NET 单元测试项目

该文件将包含一些已编写的默认代码。无需关心这些代码,只需添加以下代码即可。

创建 .NET 单元测试项目

namespace DemoApplication
{
  public class Tutorial
  {
     public String Name;
     public Tutorial()
     {
        Name = "Guru99 - ASP.Net";
     }
  }
}

Code 解释:-

  1. Name 变量是字符串类型。
  2. 最后,在 Tutorial 类的构造函数中,为 Name 变量赋值。该值被赋给“Guru99 – ASP.NET”

步骤5) 现在打开 demo.aspx 文件,添加以下代码以显示文本“Guru99 – ASP.NET。”

创建 .NET 单元测试项目

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
    <body>
    <form id="form1" runat="server">
    <div>
        <% DemoApplication.Tutorial tp=new DemoApplication.Tutorial();%>
        <%=tp.Name%>
    </div>
    </form>
    </body>
</html>

Code 解释:-

  1. 第一行代码创建了一个名为“Tutorial”的类的对象。这是使用类和对象的第一步。该对象被命名为“tp”。
  2. 最后我们从 demo.aspx 文件调用“tutorial.cs”。它显示 Name 变量的值。

当您在 Visual Studio 中运行上述程序时,您将获得以下输出。

输出:-

创建 .NET 单元测试项目

从输出结果中可以看到以下信息:“Guru99 – ASP.NET”显示。

步骤6) 现在让我们把测试项目添加到演示应用程序中。这可以通过 Visual Studio 来完成。

创建 .NET 单元测试项目

  1. 右键单击解决方案 - DemoApplication。
  2. 在上下文菜单中,选择“新建项目”选项。

步骤7) 该步骤涉及将单元测试项目添加到演示应用程序。

创建 .NET 单元测试项目

  1. 单击左侧面板中的项目类型“测试”。
  2. 从对话框中心部分的列表中选择“单元测试项目”项。
  3. 为测试项目命名。在我们的例子中,给出的名称是“DemoTest”。
  4. 最后,单击“确定”按钮。

您最终将看到 DemoTest 项目添加到解决方案资源管理器中。同时,您还可以看到默认生成的其他文件,如 UnitTest1.cs、属性等。

创建 .NET 单元测试项目

运行测试项目

前面章节中创建的测试项目用于测试我们的 ASP.NET 应用程序。接下来,我们将了解如何运行该测试项目。

  • 第一步是添加对 ASP.NET 项目的引用。执行此步骤是为了让测试项目能够访问 ASP.NET 项目。
  • 然后我们来编写我们的测试代码。
  • 最后,我们将使用 Visual Studio 运行测试。

步骤1) 要测试我们的演示应用程序,第一个测试项目需要引用演示应用程序。添加对 Demo.aspx 解决方案的引用。

运行 .NET 测试项目

  1. 右键单击 Demo Test 项目
  2. 从菜单中选择添加->引用选项。

步骤2) 下一步是添加对 DemoApplication 的引用。

运行 .NET 测试项目

  1. 从对话框左侧选择“项目”选项
  2. 单击 DemoApplication 旁边的复选框
  3. 单击“确定”按钮。

这将允许 demotest 项目测试我们的 DemoApplication。

步骤3) 现在是时候将测试代码添加到我们的测试项目中了。

  • 首先在解决方案资源管理器中双击 UnitTest1 文件(创建测试项目时,Visual Studio 会自动添加 UnitTest1 文件)。
  • 这是用于测试 ASP.NET 项目的文件。

运行 .NET 测试项目

您将看到 Visual Studio 在 UnitTest1.cs 文件中添加了以下代码。这是测试项目运行所需的基本代码。

运行 .NET 测试项目

步骤4) 下一步是添加用于测试字符串“Guru99 – ASP.NET。”

运行 .NET 测试项目

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DemoApplication;

namespace DemoTest
{
 [TestClass]
 public class UnitTest1
 {
   [TestMethod]
   public void TestMethod1()
   {
      Tutorial tp = new Tutorial();
      Assert.AreEqual(tp.Name,"Guru99 - ASP.Net");
   }
 }
}
  1. 创建一个名为“tp”的新对象,类型为“教程”
  2. 在 .NET 中,Assert.AreEqual 方法用于测试一个值是否等于某个值。因此,在本例中,我们将 tp.Name 的值与另一个值进行比较。 Guru99 – ASP.NET。

步骤5) 现在让我们运行测试项目。为此,我们需要转到菜单选项“测试”->“运行”->“所有测试”。

运行 .NET 测试项目

输出:-

运行 .NET 测试项目

Visual Studio 中将出现一个测试资源管理器窗口。这将显示上述结果,并显示在 Visual Studio 中成功运行了测试。

您将使用的 MSTest 属性和断言

此 Microsoft.VisualStudio.TestTools.UnitTesting 命名空间提供了一小套属性和断言,足以涵盖大多数 ASP.NET 单元测试。先学习这些内容,能让后续的测试更易于阅读和维护。

  • [测试类] – 将此类标记为测试容器。MSTest 会在发现类时扫描具有此属性的类。
  • [测试方法] – 将一个公共的、无参数的方法标记为单独的测试。该方法返回 void、Task 或 ValueTask。
  • [TestInitialize] / [TestCleanup] – 在每个测试方法之前和之后运行。使用它们来创建和释放共享设置,例如模拟存储库或内存上下文。
  • [类初始化] / [类清理] – 只需运行一次即可覆盖整个班级。当设置成本较高时,例如创建测试数据库,这种方法非常有用。
  • [DataRow] 和 [DataTestMethod] – 提供参数化输入,以便单一测试方法可涵盖多种情况。

在每个测试方法内部,断言类都会检查结果。常见的调用包括:`Assert.AreEqual` 用于值比较,`Assert.IsTrue` 和 `Assert.IsFalse` 用于布尔值比较,`Assert.IsNull` 和 `Assert.IsNotNull` 用于引用比较,以及 `Assert.ThrowsException` 用于抛出预期异常。使用“安排、执行、断言”模式来构建每个测试,这样设置、调用和验证步骤在视觉上就分开了。这种布局使得失败的测试易于调试,因为失败的代码行几乎总是位于最底部的单个断言语句。

MSTest、NUnit 和 xUnit 在 ASP.NET 中的比较

.NET 生态系统中主要有三个测试框架。每个框架都在 Visual Studio 中运行并与 dotnet test 集成,因此它们之间的区别主要在于风格、社区支持和默认行为。

  • MSTest 由 Microsoft 它预装了本教程前面用到的 Visual Studio 单元测试项目模板。对于刚开始接触单元测试的团队来说,这是最安全的默认设置。 Microsoft 叠加。
  • NUnit – 三者中最古老的一个,最初移植自 JUnit它提供了丰富的约束模型、通过 TestCase 和 TestCaseSource 实现的参数化测试,以及对每个 .NET 版本的成熟支持。
  • xUnit.net – 由 ASP.NET Core 和 Entity Framework Core 团队内部使用。它用构造函数和 IDisposable 替换了 SetUp 方法,鼓励每个行为使用一个测试类,并使用 [Fact] 和 [Theory] ​​代替 [TestMethod]。

这三个框架都通过属性发现测试,通过 dotnet test 命令运行测试,并生成 trx 或 xUnit XML 报告,供 CI 管道等使用。 Azure DevOps、GitHub Actions 和 Jenkins 可以直接使用。对于第一个 ASP.NET 项目,使用 MSTest 可以简化工具链。而那些需要更丰富的参数化功能或已经在使用 ASP.NET Core 的团队,通常会选择 xUnit,以保持与所用框架的一致性。

ASP.NET 应用程序单元测试最佳实践

遵循一些简单的习惯,就能使 ASP.NET 套件在项目的整个生命周期内保持快速、可靠和实用。

  1. 每种方法测试一种行为。 一项测试如果断言几个不相关的事项,会因为多种原因而失败,而且修复起来也需要更长时间。
  2. 命名测试应遵循意图。 MethodUnderTest_Scenario_ExpectedResult 之类的模式使测试资源管理器能够输出类的可读规范。
  3. 将设备与外部系统隔离。 将文件、网络和数据库调用封装在接口之后,并替换为伪造或模拟对象,以便测试不会遇到真正的依赖项。
  4. 加快测试速度。 目标是让整个单元测试套件在几秒钟内完成。耗时的测试会被跳过,而跳过的测试会掩盖回归问题。
  5. 遵循“安排、行动、陈述”的流程。 三个短方块之间用空白行隔开,表示意图,并使出错的行容易被发现。
  6. 每次提交都运行测试。 将 .NET 测试集成到 CI 流水线中,这样,如果测试失败,就不会导致合并失败,而是阻止合并。ping 到生产。
  7. Track 代码覆盖率,但不要过分追求。 覆盖率可以突出显示未经测试的路径,但高覆盖率本身并不能保证质量。 Rev查看缺失的线路实际执行了什么操作。

这些实践结合起来,可以将上面构建的 DemoTest 项目变成一个套件的雏形,该套件可以在每次推送时捕获回归,为未来的开发人员记录行为,并在重构 ASP.NET 应用程序时提供信心。

常见问题

是的。GitHub Copilot 可以生成 [TestClass] 和 [TestMethod] 代码块,建议 Arrange Act Assert 布局,并根据目标方法签名生成参数化的 [DataRow] 用例。 Rev在生产环境中使用之前,请先查看生成的断言。

是的。基于机器学习的辅助工具可以标记脆弱的测试用例,建议更合适的名称,并突出显示应该放在 [TestInitialize] 中的重复设置。它们可以缩短审查时间,但开发人员仍然对每个断言的正确性负责。

单元测试隔离单个类或方法,并模拟其依赖项。集成测试则同时测试多个组件,通常会访问真实的数据库或 Web 服务器。单元测试只需几毫秒即可完成;集成测试耗时更长,但可以发现代码错误。

在 Visual Studio Enterprise 中,使用测试分析 Code 涵盖所有测试。在其他版本中,请添加 Coverlet N。uGet 打包并运行 dotnet test –collect:”XPlat Code 覆盖范围”以产生 Cobertura XML报告。

将依赖项封装在一个接口中,并通过构造函数注入。在测试中,传递一个使用 Moq 或 NSubstitute 等库构建的桩对象或模拟对象,这样被测单元就不会直接访问真实的数据库或 HTTP 端点。

在包含测试项目的文件夹中运行 `dotnet test` 命令。该命令会构建项目,发现每个 `[TestMethod]`,执行它们,并打印摘要。诸如 GitHub Actions 之类的持续集成系统会在工作流步骤中调用相同的命令。

使用 [DataTestMethod] 标记该方法,并添加一个或多个 [DataRow] 属性来提供输入值和预期结果。然后,MSTest 会针对每一行运行相同的测试体,并在测试资源管理器中为每个测试用例生成单独的一行。

编写一个会失败的 [TestMethod] 来描述下一个所需的行为,添加足够的生产代码使其通过测试,然后重构。重复这个红绿灯重构循环,可以确保设计由测试驱动,而不是反过来。

总结一下这篇文章: