如何在每个类测试后运行ClassCleanup(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(); } 

测试无序运行,包括跨类测试。 看到这篇博文:

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方法也可以推迟到所有测试用例都已执行。

不幸的是,如果这对您不起作用,您将不得不查看有序测试或不同的unit testing框架。

有一个名为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 

我做了一些测试,并在类中使用静态字段来“告诉”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(); } } 

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

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