创建数据驱动的单元测试

发布时间:2025-02-28 00:49

掌握数据驱动决策的方法,如数据分析和预测模型 #生活技巧# #领导力技巧# #决策科学#

跳转至主内容

此浏览器不再受支持。

请升级到 Microsoft Edge 以使用最新的功能、安全更新和技术支持。

创建数据驱动单元测试

项目2025/02/13

本文内容

正在测试的方法对测试方法进行测试运行测试和查看结果相关内容

可以使用托管代码的 Microsoft 单元测试框架 (MSTest) 设置单元测试方法以从数据源检索值。 该方法针对数据源中的每个行连续运行,这样就可以使用单个方法轻松测试各种输入。

数据驱动单元测试可以使用以下任一类型:

使用 DataRow 属性的内联数据 使用 DynamicData 属性的成员数据 来自一些使用 DataSource 属性的已知源提供程序

正在测试的方法

例如,假设你有:

名为 MyBank 的解决方案,可接受和处理不同类型的帐户的事务。

MyBank 中名为 BankDb 的项目,用于管理帐户的事务。

BankDb 项目中名为 Maths 的类,用于执行数学函数以确保任何事务对银行有利。

名为 BankDbTests 的单元测试项目,用于测试 BankDb 组件的行为。

名为 MathsTests 的单元测试类,用于验证 Maths 类的行为。

我们将在 Maths 中测试使用循环添加两个整数的方法:

public int AddIntegers(int first, int second) { int sum = first; for (int i = 0; i < second; i++) { sum += 1; } return sum; }

对测试方法进行测试

内联数据驱动的测试

对于内联测试,MSTest 使用 DataRow 来指定数据驱动测试使用的值。 此示例中的测试针对每个数据行连续运行。

[TestMethod] [DataRow(1, 1, 2)] [DataRow(2, 2, 4)] [DataRow(3, 3, 6)] [DataRow(0, 0, 1)] // The test run with this row fails public void AddIntegers_FromDataRowTest(int x, int y, int expected) { var target = new Maths(); int actual = target.AddIntegers(x, y); Assert.AreEqual(expected, actual, "x:<{0}> y:<{1}>", new object[] {x, y}); }

成员数据驱动的测试

MSTest 使用 DynamicData 属性来指定成员的名称、类型和定义类型(默认使用当前类型),该成员将提供数据驱动测试使用的数据。

备注

在 MSTest 3.8 之前,DynamicDataSourceType 枚举具有两个成员,Property 和 Method。 默认值为 Property。 从 MSTest 3.8 开始,新成员 AutoDetect 添加到枚举中,这是默认值。 因此,不再需要指定 DynamicDataSourceType。

public static IEnumerable<object[]> AdditionData { get { return new[] { new object[] { 1, 1, 2 }, new object[] { 2, 2, 4 }, new object[] { 3, 3, 6 }, new object[] { 0, 0, 1 }, // The test run with this row fails }; } } [TestMethod] [DynamicData(nameof(AdditionData))] public void AddIntegers_FromDynamicDataTest(int x, int y, int expected) { var target = new Maths(); int actual = target.AddIntegers(x, y); Assert.AreEqual(expected, actual, "x:<{0}> y:<{1}>", new object[] {x, y}); }

还可以使用 DynamicData 属性的 DynamicDataDisplayName 属性替代默认生成的显示名称。 显示名称方法签名必须 public static string 并接受两个参数,第一个类型 MethodInfo 和第二个类型 object[]。

public static string GetCustomDynamicDataDisplayName(MethodInfo methodInfo, object[] data) { return string.Format("DynamicDataTestMethod {0} with {1} parameters", methodInfo.Name, data.Length); } [DynamicData(nameof(AdditionData), DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))]

源提供程序数据驱动的测试

创建数据源驱动的单元测试涉及以下步骤:

创建一个数据源,其中包含在测试方法中使用的值。 数据源可以是任何在运行测试的计算机上注册的类型。

将 TestContext 类型的公共 TestContext 属性添加到测试类。

创建单元测试方法

向其添加 DataSourceAttribute 属性。

使用 DataRow 索引器属性检索在测试中使用的值。

创建数据源

若要测试 AddIntegers 方法,请创建一个数据源,该数据源指定参数的一系列值以及预期返回的总和。 在本示例中,我们将创建名为 MathsData 的 Sql Compact 数据库和包含以下列名和值的名为 AddIntegersData 的表

FirstNumber SecondNumber Sum 0 1 1 1 1 2 2 -3 -1 将 TestContext 添加到测试类

单元测试框架创建一个 TestContext 对象,用于存储数据驱动测试的数据源信息。 然后,框架将此对象设置为所创建的 TestContext 属性的值。

public TestContext TestContext { get; set; }

在您的测试方法中,您可以通过 TestContext的 DataRow 索引器属性访问数据。

备注

.NET Core 不支持 DataSource 属性。 如果尝试在.NET Core、UWP 或 WinUI 单元测试项目中以这种方式访问测试数据,您可能会看到与 "‘TestContext’ 不包含 'DataRow' 的定义,且找不到接受 'TestContext' 类型的第一个参数的可访问扩展方法 'DataRow'" 类似的错误(是否缺少 using 指令或程序集引用?)

编写测试方法

AddIntegers 的测试方法非常简单。 对于数据源中的每个行,请使用 FirstNumberSecondNumber 列值作为参数调用 AddIntegers,并针对 Sum 列值验证返回值:

[TestMethod] [DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")] public void AddIntegers_FromDataSourceTest() { var target = new Maths(); // Access the data int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]); int y = Convert.ToInt32(TestContext.DataRow["SecondNumber"]); int expected = Convert.ToInt32(TestContext.DataRow["Sum"]); int actual = target.AddIntegers(x, y); Assert.AreEqual(expected, actual, "x:<{0}> y:<{1}>", new object[] {x, y}); } 指定 DataSourceAttribute

DataSource 属性指定数据源的连接字符串以及测试方法中使用的表的名称。 连接字符串中的确切信息会有所不同,具体取决于所使用的数据源类型。 在此示例中,我们使用了 SqlServerCe 数据库。

[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0;Data Source=C:\Data\MathsData.sdf", "AddIntegersData")]

注意

连接字符串可以包含敏感数据(例如密码)。 连接字符串以纯文本形式存储在源代码和已编译的程序集中。 限制对源代码和程序集的访问以保护此敏感信息。

DataSource 属性有三个构造函数。

[DataSource(dataSourceSettingName)]

具有一个参数的构造函数使用存储在解决方案 app.config 文件中的连接信息。 dataSourceSettingsName 是配置文件中指定连接信息的 Xml 元素的名称。

使用 app.config 文件可以更改数据源的位置,而无需更改单元测试本身。 有关如何创建和使用 app.config 文件的信息,请参阅 演练:使用配置文件定义数据源

[DataSource(connectionString, tableName)]

具有两个参数的 DataSource 构造函数指定数据源的连接字符串和包含测试方法数据的表的名称。

连接字符串取决于数据源类型的类型,但它应包含一个提供程序元素,该元素指定数据提供程序的固定名称。

[DataSource( dataProvider, connectionString, tableName, dataAccessMethod )] 使用 TestContext.DataRow 访问数据

若要访问 AddIntegersData 表中的数据,请使用 TestContext.DataRow 索引器。 DataRow 是一个 DataRow 对象,因此按索引或列名检索列值。 由于这些值作为对象返回,因此将它们转换为适当的类型:

int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);

运行测试和查看结果

编写完测试方法后,生成测试项目。 测试方法显示在 测试资源管理器未运行测试 组中。 运行、写入和重新运行测试时,测试资源管理器失败的测试组、通过的测试以及 未运行测试显示结果。 可以选择 运行所有 来运行所有测试,或选择 运行 选择要运行的测试子集。

当运行测试时,位于“测试资源管理器”顶部的测试结果栏是动态显示的。 在测试运行结束时,如果所有测试都已通过,则条形图将为绿色,如果任何测试均失败,则为红色。 测试运行摘要显示在 测试资源管理器 窗口底部的详细信息窗格中。 选择一个测试,在底部窗格中查看该测试的详细信息。

备注

每行数据都有一个结果,还有一个摘要结果。 如果每行数据测试均通过,则摘要运行显示为“已通过”。 如果测试在任何数据行上失败,摘要运行将显示为 失败

如果在示例中运行了任何 AddIntegers_FromDataRowTest、AddIntegers_FromDynamicDataTest 或 AddIntegers_FromDataSourceTest 方法,结果栏将变为红色,并且测试方法将移动到 失败的测试区。 如果数据源中的任何迭代方法失败,数据驱动测试将失败。 在 测试资源管理器 窗口中选择失败的数据驱动测试时,详细信息窗格将显示数据行索引标识的每个迭代的结果。 在我们的示例中,AddIntegers 算法似乎未正确处理负值。

当测试中的方法得到更正并重新运行测试时,结果栏变为绿色,并将测试方法移动到 通过的测试 组。

相关内容

Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute Microsoft.VisualStudio.TestTools.UnitTesting.TestContext Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DataRow Microsoft.VisualStudio.TestTools.UnitTesting.Assert 单元测试代码 使用测试资源管理器运行单元测试 使用 Microsoft 单元测试框架为 .NET 编写单元测试

反馈

网址:创建数据驱动的单元测试 https://www.yuejiaxmz.com/news/view/798340

相关内容

创建简单的数据驱动 CRUD 微服务
大数据驱动下的建筑材料创新
数据驱动的数字化转型:从流程驱动到数据驱动
数据驱动到底是什么?如何驱动,又能驱动什么?
10个AI驱动的软件测试自动化工具,你尝试过吗?
数据库压力测试详解
盘点15个用于自动化单元测试的人工智能工具
DOM驱动和数据驱动的区别【浅显易懂】
理解服务中数据驱动及实现方式
数据驱动服务 舒福德开启数字睡眠新纪元

随便看看