【问题标题】:Is there a way to use data that's already in memory to drive unit tests?有没有办法使用内存中的数据来驱动单元测试?
【发布时间】:2016-01-29 21:12:06
【问题描述】:

我知道我可以使用文件中的数据来驱动单元测试,例如 csv 或 xml 文件中的数据。

例如:

[TestMethod]
[DataSource(
    "Microsoft.VisualStudio.TestTools.DataSource.CSV", 
    "Data.csv", 
    "Data#csv", 
    DataAccessMethod.Sequential)]
public void TestData() {}

我想知道是否有一种方法可以代替使用文件,而是使用内存中的数据结构来驱动测试。

类似:

// this structure has the data to use in the unit test
var DataList = new List<string>();

[TestMethod]
[DataSource(
    "Microsoft.VisualStudio.TestTools.DataSource.IEnumerable",
    "DataList", 
    "DataList", 
    DataAccessMethod.Sequential)]
public void TestData() {}

【问题讨论】:

标签: c# visual-studio-2010 mstest data-driven-tests


【解决方案1】:

如果它在内存中,我的偏好是不使用 DataSource,而是使用 T4 模板自动生成您的单元测试。这样,您将只编写一次测试,但在测试运行的结果中,您将看到您测试的每个输入的条目。将此 .tt 文件添加到您的测试项目中。

<#@ template debug="false" hostspecific="true" language="C#v3.5" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ output extension=".cs" #>
<#
        List<string> DataList = AccessInMemoryData();
#>
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1
{
[TestClass]
public class UnitTest1
{
    <# foreach (string currentTestString in DataList) { #>
    [TestMethod]
    public void TestingString_<#= currentTestString #>
    {
    string currentTestString = "<#= currentTestString #>";
    // TODO: Put your standard test code here which will use the string you created above
    }
    <# } #>
}
}

【讨论】:

    【解决方案2】:

    一个简单的解决方案可以是这样...

    private void TestData(IEnumerable what ) { ... your test method ... }
    
    [TestMethod]
    public void TestDataInMemory() { List<T> mylist = ...; this.TestData(mylist); }
    
    [TestMethod]
    [DataSource(
        "Microsoft.VisualStudio.TestTools.DataSource.CSV", 
        "Data.csv", 
        "Data#csv", 
        DataAccessMethod.Sequential)]
    public void TestData() { this.TestData(testContextInstance ...) }
    

    通过这种方式,您可以对从文件加载的数据和从内存加载的数据使用您的测试方法。

    【讨论】:

    • 感谢您的建议。不幸的是,在我看来,TestDataInMemory() 测试只会针对任意数量的数据条目运行一次,而 TestData() 测试将针对每个条目运行一次。出于我的目的,我宁愿每个条目运行一个测试。
    【解决方案3】:

    我不认为你可以用 [DataSource] 属性做到这一点,但你可以手动做或多或少相同的事情。

    在使用[AssemblyInitialize][ClassInitialize] 修饰的方法中加载数据。然后重写你的测试来循环数据。不幸的是,这样你最终会得到一个单独的测试,而不是每次测试运行的单独结果。

    【讨论】:

    • 是的,数据已经在[ClassInitialize]函数中设置好了,我尝试了你的建议。它确实有效,但是对所有数据进行一次测试意味着断言将在第一次失败的测试时停止该功能。不是我想要的。感谢您的建议。
    【解决方案4】:

    answeredsimilar question 之前使用的解决方案是从我的内存数据生成一个简单的 CSV 文件。

    【讨论】:

      【解决方案5】:

      您可以通过 NuGet 使用 MSTestHacks 从 IEnumerable 提供数据,请参阅 this answer

      【讨论】:

        【解决方案6】:

        我认为Gallio Ambience 应该可以解决这个问题。我不确定该项目目前的状态。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-23
          • 1970-01-01
          • 2020-04-28
          • 2017-08-03
          • 1970-01-01
          • 1970-01-01
          • 2010-12-05
          相关资源
          最近更新 更多