如何在每个类测试后运行ClassCleanup(MSTest)?

时间:2014-06-09 09:17:26

标签: c# .net mstest

我有几个带有测试套件的课程。

每个测试类从ClassInitialize开始,并由ClassCleanup完成。 我的问题是ClassCleanup没有在每个类的末尾调用,只有在三个类中的所有测试之后才调用它。 我能解决这个问题吗?谢谢!

[ClassInitialize]
public static void SetUpBrowser(TestContext context)
{
    pageObjectBase.SetBrowser("chrome");
    pagesManager.GetPageObjectBase();
}

[TestMethod]
public void FindCriticalBug()
{
    bla-bla-bla();
}

[ClassCleanup]
public static void CloseBrowser()
{
    pageObjectBase.Stop();
    pagesManager.GeneralClearing();
}

4 个答案:

答案 0 :(得分:13)

测试无序运行,包括跨类测试。请参阅此博客文章:

http://blogs.msdn.com/b/ploeh/archive/2007/01/06/classcleanupmayrunlaterthanyouthink.aspx

引用:

  

无论如何,这是我的输出窗口的结果:

AssemblyInitialize
TestClass1: ClassInitialize
TestClass1: TestInitialize
TestClass1: MyTestCase1
TestClass1: TestCleanup
TestClass2: ClassInitialize
TestClass2: TestInitialize
TestClass2: MyTestCase2
TestClass2: TestCleanup
TestClass1: ClassCleanup
TestClass2: ClassCleanup
AssemblyCleanup
     

...这并不代表TestClass1的ClassCleanup在类中的最后一个测试用例之后立即执行!实际上,它等待所有测试用例执行,然后执行   与TestClass2的ClassCleanup一起使用。

     

起初这让我感到惊讶,但这显然只是因为我   我没有真正想过:原则上,测试是   无序的,不能保证TestClass1中的所有测试都是   立即执行。从理论上讲,执行引擎   可以从TestClass1中选择一个测试用例,然后从TestClass2中选择一个   另一个来自TestClass1等。既然如此,那就没有了   保证之前执行过一个测试类的所有测试   一个新的测试类被初始化,因此,所有ClassCleanup方法   也可以推迟到所有测试用例都已执行之后。

不幸的是,如果这对您不起作用,您必须查看有序测试或不同的单元测试框架。

答案 1 :(得分:5)

有一个名为TestCleanupAttribute的不同属性,它将在每次测试后运行。

在每个名为TestInitializeAttribute的测试之前还有一个属性要运行。

以下是一起运行的示例。

[TestClass]
public class MyTests
{
   [ClassInitialize]
   public void ClassInitialize() { Debug.Print("Running ClassInitialize"); }

   [TestInitialize]
   public void TestInitialize() { Debug.Print("Running    TestInitialize"); }

   [TestMethod]
   public void TestMethod1() { Debug.Print("Running       TestMethod1....."); }

   [TestMethod]
   public void TestMethod2() { Debug.Print("Running       TestMethod2....."); }

   [TestCleanup]
   public void TestCleanup() { Debug.Print("Running    TestCleanup"); }

   [ClassCleanup]
   public void ClassCleanup() { Debug.Print("Running ClassCleanup"); }
}

这将导致

Running ClassInitialize
Running    TestInitialize
Running       TestMethod1.....
Running    TestCleanup
Running    TestInitialize
Running       TestMethod2.....
Running    TestCleanup
Running ClassCleanup

答案 2 :(得分:3)

我做了一些测试并在课堂上使用静态字段来告诉"所有方法运行的TestCleanup方法似乎都有效。然后,您可以删除ClassCleanup并执行以下操作:

private static int runs = 0;

[ClassInitialize]
public static void SetUpBrowser(TestContext context)
{
    pageObjectBase.SetBrowser("chrome");
    pagesManager.GetPageObjectBase();
}

[TestMethod]
public void FindCriticalBug()
{
    runs++;
    bla-bla-bla();
}

[TestMethod]
public void FindCriticalBug2()
{
    runs++;
    ble-ble-ble();
}

[TestCleanup]
public static void CloseBrowser()
{
    if (runs == 2)
    {
        pageObjectBase.Stop();
        pagesManager.GeneralClearing();
    }
}

尽管如此,我仍然非常远离此解决方案,但如果您没有其他选择,并且您无法重构您的设计以使用提供的生命周期,则可能是一个选择。你可能会在这里变得更加漂亮并编写自己的基类来计算执行次数并使用反射来获取测试方法的总量来自动化这些东西。

答案 3 :(得分:1)

正常单位测试是“无序的”,这意味着它们可以按任何顺序运行。您可能正在寻找有序测试之类的东西(请参阅您对dominic的评论)。有序测试是一个特殊的单元测试项目。运行有序测试时,测试将运行如何配置它们,并在完成时拆除测试类。如果单元测试必须按顺序运行,则测试相互干扰的气味。干扰测试是不可靠的,因为它们失败是因为早期测试留下了一些不良数据或测试它自身失败。您无法知道代码的真正错误。