如何:创建数据驱动的单元测试

使用 Microsoft 单元测试框架用于托管代码,您可以设置单元测试方法来检索数据源的测试方法中使用的值。连续运行方法时更加方便地使用一个方法来测试不同的输入数据源中的每一行。

本主题包含以下各节:

创建数据驱动的单元测试包括以下步骤:

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

  2. 添加一个私有TestContext字段和公共TestContext属性设置为该测试类。

  3. 创建单元测试方法,并添加DataSourceAttribute给它的属性。

  4. 使用DataRow索引器属性,以检索您的测试中使用的值。

测试方法

例如,假设我们已创建:

  1. 解决方案名为MyBank的接受和处理不同类型的帐户的交易记录。

  2. 项目中, MyBank名为BankDb ,管理帐户的交易记录。

  3. 类名为Maths在DbBank执行数学函数,以确保任何交易记录的银行有利的项目。

  4. 单元测试项目名为BankDbTests测试行为的BankDb组件。

  5. 单元测试类名为MathsTests验证行为的Maths类。

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

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

创建数据源

若要测试AddIntegers方法,我们将创建数据源的指定参数和返回您所期望的总和的值的范围。在我们的示例中,我们创建一个名为 Sql 压缩数据库MathsData和表名为AddIntegersData包含下面的列名称和值

FirstNumber

SecondNumber

Sum

0

1

1

1

1

2

2

-3

-1

将 TestContext 添加到测试类

创建单元测试框架TestContext对象存储为数据驱动测试的数据源信息。框架然后将该对象设置的值为TestContext ,我们创建的属性。

    private TestContext testContextInstance;
    public TestContext TestContext
    {
        get { return testContextInstance; }
        set { testContextInstance = value; }
    }

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

编写测试方法

测试方法的AddIntegers相当简单。对于数据源中的每一行,我们调用AddIntegers与 FirstNumberSecondNumber 列的值作为参数,并在我们验证针对的返回值列中的值:


    [DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")]
    [TestMethod()]
    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.IntegerMethod(x, y);
        Assert.AreEqual(expected, actual,
            "x:<{0}> y:<{1}>",
            new object[] {x, y});

    }

请注意, Assert方法包括一条消息,显示x和y失败的小版本的值。默认情况下断言的值, expected和actual,已经包括在测试失败的详细信息。

ms182527.collapse_all(zh-cn,VS.110).gif指定 DataSourceAttribute

DataSource属性指定的数据源和表,您使用的名称的连接字符串中的测试方法。根据使用的数据源的种类,连接字符串中的确切信息会有所不同。在此示例中,我们使用 SqlServerCe 数据库。

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

数据源属性中有三个构造函数。

[DataSource(dataSourceSettingName)]

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

使用一个 app.config 文件允许您更改数据源的位置,而不进行单元测试本身的更改。有关如何创建和使用 app.config 文件的信息,请参阅演练:使用配置文件定义数据源

[DataSource(connectionString, tableName)]

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

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

[DataSource(
    dataProvider, 
    connectionString, 
    tableName,
    dataAccessMethod
    )]

ms182527.collapse_all(zh-cn,VS.110).gif使用 TestContext.DataRow 来访问数据

若要访问的数据中AddIntegersData表,请使用TestContext.DataRow索引器。DataRow是DataRow对象,所以我们通过索引或列名检索列的值。作为对象返回的值,因为我们需要将它们转换为适当的类型:

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

运行测试并查看结果

编写测试方法完成后,生成的测试项目。测试方法的测试资源管理器窗口中将出现不运行测试组。运行、 编写,并重新运行测试后,测试资源管理器中显示一组结果失败测试传递测试,和 不运行测试。您可以选择运行所有 运行所有测试,或选择 **都运行...**选择要运行的测试的一个子集。

在测试运行的资源管理器顶部的测试结果栏会呈现动画效果。在测试运行结束时,栏将是如果所有测试已通过绿色或红色,如果任何测试失败。测试运行的摘要会显示在详细信息窗格底部的测试资源管理器窗口中。选择一个测试,在底部窗格中查看该测试的详细信息。

如果您运行AddIntegers_FromDataSourceTest方法在我们的示例中,结果栏将变为红色并测试方法被移到失败测试数据驱动测试失败,如果任何一种迭代方法从数据源无法正常工作。当您测试的浏览器窗口中选择数据驱动测试失败时,详细信息窗格显示由数据行索引标识每个迭代的结果。在我们的示例中,显示的AddIntegers算法不能正确处理值为负。

当更正的方法进行测试和重新运行测试,结果栏变为绿色和测试方法移动到传递测试组。

请参见

参考

Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute

Microsoft.VisualStudio.TestTools.UnitTesting.TestContext

TestContext.DataRow

Microsoft.VisualStudio.TestTools.UnitTesting.Assert

概念

使用单元测试验证代码

用 Microsoft 适用于托管代码的单元测试框架编写 .NET Framework 的单元测试

其他资源

如何:创建和运行单元测试

用测试资源管理器运行单元测试