简体   繁体   English

如何按课程隔离单元测试?

[英]How can I isolate unit tests by class?

I have a number of 'unit tests' (they're really integration tests) in several classes that access a shared resource, and I want each test class to only acquire the resource once (for performance reasons). 我在访问共享资源的几个类中有许多“单元测试”(它们实际上是集成测试),并且我希望每个测试类仅获取一次资源(出于性能原因)。

However, I'm getting issues when I release the resource in [ClassCleanup] , because that isn't running until all tests are completed. 但是,当我在[ClassCleanup]释放资源时遇到了问题,因为直到所有测试完成,该资源才会运行。

Here's a simplified example: 这是一个简化的示例:

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
    }
}

On my machine at least, TestB fails because it runs before ClassA has been cleaned up. 至少在我的机器上, TestB失败,因为它在清除ClassA之前运行。

I read ClassCleanup May Run Later Than You Think , but that doesn't explain any way to change the behaviour. 我读过ClassCleanup可能比您想的晚 ,但是这并不能解释改变行为的任何方法。 And I realize I shouldn't depend on test ordering, but it's too expensive to re-acquire the resource for every test, so I want to group them by class. 而且我意识到我不应该依赖于测试顺序,但是为每个测试重新获取资源太昂贵了,因此我想按类对它们进行分组。

How can I fix this? 我怎样才能解决这个问题? Is there a way to force each test class to run as a unit, and make the cleanup occur immediately? 有没有一种方法可以强制每个测试类作为一个单元运行,并使清除立即进行?

Although ClassCleanup might be unreliable in terms of when it is run, ClassInitialize is not; 尽管就何时运行而言, ClassCleanup可能并不可靠,但ClassInitialize却并非如此。 why not give each testclass that relies on this shared resource a ClassInitialize that cleans up the shared resource of the previous test class (if any), right before acquiring the resource itself? 为什么不给每个依赖于此共享资源的测试类一个ClassInitialize ,以便在获取资源本身之前就清除先前测试类(如果有)的共享资源?

The only time the shared resource isn't released is for the last test class, but you could handle that with the ClassCleanup because then it doesn't matter anymore when it is run (since there won't be any more test classes following it). 唯一不释放共享资源的时间是针对最后一个测试类,但是您可以使用ClassCleanup来处理它,因为这样,当它运行时就不再重要了(因为在它后面将不再有测试类了) )。

Is there any reason that you cannot make this resource shared by the entire assembly all at once? 有什么原因不能使该资源一次全部由整个程序集共享? Make it an internal or public static variable in one of the test classes (or a separate designated class), and refer to it directly from all the test classes. 在一个测试类(或单独的指定类)中将其设为内部或公共静态变量,并直接从所有测试类中引用它。 The initialization of the resource will take place in the [AssemblyInitialize] method and the cleanup will take place at the [AssemblyCleanup]. 资源的初始化将在[AssemblyInitialize]方法中进行,清除将在[AssemblyCleanup]中进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM