如何按班级隔离单元测试?

时间:2014-07-25 12:41:58

标签: c# visual-studio unit-testing integration-testing mstest

我在几个访问共享资源的类中有许多“单元测试”(它们实际上是集成测试),我希望每个测试类只获取一次资源(出于性能原因)。

但是,当我在[ClassCleanup]中发布资源时,我遇到了问题,因为直到所有测试都完成后才会运行。

这是一个简化的例子:

using Microsoft.VisualStudio.TestTools.UnitTesting;

static class State
{
    public static string Thing;
}
[TestClass]
public class ClassA
{
    [ClassInitialize]
    public static void Initialize(TestContext ctx)
    {
        State.Thing = "Hello, World!";
    }
    [ClassCleanup]
    public static void Cleanup()
    {
        State.Thing = null;
    }
    [TestMethod]
    public void TestA()
    {
        Assert.IsNotNull(State.Thing); // Verify we have a good state
    }
}
[TestClass]
public class ClassB
{
    [TestMethod]
    public void TestB()
    {
        Assert.IsNull(State.Thing); // Verify we have an uninitialized state
        // Initialize state, do stuff with it
    }
}

至少在我的计算机上,TestB失败,因为它在清除ClassA之前运行。

我读过ClassCleanup May Run Later Than You Think,但这并没有解释任何改变行为的方法。我意识到我不应该依赖于测试排序,但是为每次测试重新获取资源都太昂贵了,所以我想按类对它们进行分组。

我该如何解决这个问题?有没有办法强制每个测试类作为一个单元运行,并立即进行清理?

2 个答案:

答案 0 :(得分:0)

虽然ClassCleanup在运行时可能不可靠,但ClassInitialize不是;为什么不在获取资源本身之前给依赖于此共享资源的每个测试类ClassInitialize清除先前测试类的共享资源(如果有的话)?

共享资源未发布的唯一时间是针对最后一个测试类,但您可以使用ClassCleanup处理该资源,因为它在运行时不再重要(因为之后不再有测试类了。)

答案 1 :(得分:0)

是否有任何原因导致您无法一次性将整个程序集共享此资源?使其成为其中一个测试类(或单独的指定类)中的内部或公共静态变量,并直接从所有测试类中引用它。资源的初始化将在[AssemblyInitialize]方法中进行,清理将在[AssemblyCleanup]进行。