繁体   English   中英

如何在每个 class 之后运行 ClassCleanup (MSTest) 并进行测试?

[英]How to run ClassCleanup (MSTest) after each class with test?

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

每个测试 class 从 ClassInitialize 开始并由 ClassCleanup 完成。 我的问题是在每个 class 的末尾都没有调用 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();
}

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

https://docs.microsoft.com/archive/blogs/ploeh/classcleanup-may-run-later-than-you-think

报价:

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

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

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

有一个名为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();
    }
}

我会留远离这种解决方案虽然,但如果你有没有其他选择,你可以不重构你的设计中使用所提供的生命周期,它可能是一个选项。 您可能会在这里变得更有趣,并编写自己的基类来计算执行次数并使用反射获取测试方法的总量来自动化这些东西。

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

您可以使用ClassCleanupBehavior来决定何时完成清理:
MSTest v2:测试生命周期属性

您还可以自定义何时调用清理方法。 默认情况下,在执行程序集的所有测试后调用 cleanup 方法。 您可以通过使用ClassCleanupBehavior枚举来更早地调用。

ClassCleanupBehavior.EndOfAssembly :在程序集的所有测试执行后调用ClassCleanupBehavior.EndOfClass :在 class 的所有测试执行后调用 您可以使用程序集属性ClassCleanupExecution自定义全局行为。

 ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] [TestClass] public class TestClass1 { [ClassCleanup(ClassCleanupBehavior.EndOfAssembly)] public static void ClassCleanup() { Console.WriteLine("ClassCleanup"); } [TestMethod] public void Test1() { } }

暂无
暂无

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

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