【问题标题】:Forcing ClassInitialize to execute before testmethod data is read在读取测试方法数据之前强制执行 ClassInitialize
【发布时间】:2013-08-13 19:10:35
【问题描述】:

在评估单元测试的属性后,我遇到了单元测试的 classinitilalize 方法的问题。这些测试使用 [classinitialize] 方法生成测试集,该测试集在 xml 文件中生成随机数据集。 xml 文件由具有属性 [datasource] 的单元测试使用。精简版如下所示:

[ClassInitialize]
public static void Initialize(TestContext context)
{
    // Create xml output file
    var output = new XDocument(new XElement("Rows"));

    foreach (var Code in Codes)
    {
        if (output.Root != null) 
            output.Root.Add(new XElement("Row", new XElement("Code", Code)));
    }
    output.Save("TestData.xml");
}

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
"|DataDirectory|\\TestData.xml",
"Row",
DataAccessMethod.Sequential)]
[TestMethod]
public void TestStuff()
{
    var Code = (string)TestContext.DataRow["Code"];
    TestItem(Code);
}

我正在使用 Visual Studio 2012 Update 3。我使用了 Sysinternals 工具 Process Monitor 来验证执行顺序。我在每个方法的开头设置了一个断点。然后,我逐步查看了文件访问。我看到的操作顺序。

  1. TestData.xml 被 vstestexecutionengine 读取。
  2. 调用ClassInitialize方法并写入TestData.xml
  3. TestMethod 使用步骤 1 中读取的数据执行。(我添加了一个包含虚假数据的文件进行测试)

所以我的问题是,在读取 xml 文件之前没有执行 classinitialize 我做错了什么?还是我试图做的事情是不可能的?

【问题讨论】:

  • 我不确定,但为什么不将静态 xml 文件作为资源添加到您的测试项目中呢?恕我直言,它使测试更值得信赖。您已经知道输入和预期输出。
  • 这是一个很好的观点,选择随机子集背后的逻辑是这些行中的每一行都运行相当长的时间,并且完成整个集合需要一个多小时才能完成此测试。
  • 我一直这样做。这很方便,因为当您更改架构时,您可以保留旧结构并添加新结构,然后添加测试以了解您遇到的任何一种情况。例如处理旧版本,或抛出特定错误,或迁移到新格式,等等。

标签: c# visual-studio-2012 mstest


【解决方案1】:

MSTestHacks 可能是您可能的解决方法。

它允许将测试类上的IEnumberable 用作TestMethodDataSource。您可以在此属性中以 Codes 的形式返回您拥有的内容。

来自网站:

运行时数据源

您必须从 TestBase 继承您的测试类

[TestClass]
public class UnitTest1 : TestBase
{ }

创建一个返回IEnumerable的属性、字段或方法

[TestClass]
public class UnitTest1 : TestBase
{
    private IEnumerable<int> Stuff
    {
        get
        {
            //This could do anything, fetch a dynamic list from anywhere....
            return new List<int> { 1, 2, 3 };
        }
    }
}

DataSource 属性添加到您的测试方法中,指向之前创建的IEnumerable 名称。这需要完全限定。

[TestMethod]
[DataSource("Namespace.UnitTest1.Stuff")]
public void TestMethod1()
{
    var number = this.TestContext.GetRuntimeDataSourceObject<int>();

    Assert.IsNotNull(number);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多