Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在每个带有测试的类之后运行ClassCleanup(MSTest)?_C#_.net_Mstest - Fatal编程技术网

C# 如何在每个带有测试的类之后运行ClassCleanup(MSTest)?

C# 如何在每个带有测试的类之后运行ClassCleanup(MSTest)?,c#,.net,mstest,C#,.net,Mstest,我有几节课有测试套件 每个测试类从ClassInitialize开始,到ClassCleanup结束。 我的问题是ClassCleanup不是在每个类的末尾调用的,它只是在三个类中的所有测试之后调用的。 我可以解决这个问题吗?谢谢 [ClassInitialize] public static void SetUpBrowser(TestContext context) { pageObjectBase.SetBrowser("chrome"); pagesManager.Get

我有几节课有测试套件

每个测试类从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();
}

正常的单元测试是无序的,这意味着它们可以以任何顺序运行。您可能正在寻找类似于有序测试的东西(请参阅您对dominic的评论)。有序测试是一个特殊的单元测试项目。当运行有序测试时,测试将以您配置它们的方式运行,并在完成测试后拆除测试类。如果单元测试必须按顺序运行,则会有测试相互干扰的气味。干扰测试是不可靠的,因为它们失败是因为先前的测试留下了一些坏数据,或者测试本身失败了。您无法知道代码到底出了什么问题。

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

在调用每个测试之前,还需要运行一个属性

下面是它们一起运行的示例

[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

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

引述:

在任何情况下,以下是我的输出窗口的结果:

AssemblyInitialize
TestClass1: ClassInitialize
TestClass1: TestInitialize
TestClass1: MyTestCase1
TestClass1: TestCleanup
TestClass2: ClassInitialize
TestClass2: TestInitialize
TestClass2: MyTestCase2
TestClass2: TestCleanup
TestClass1: ClassCleanup
TestClass2: ClassCleanup
AssemblyCleanup
…这并不意味着TestClass1的类清理会在类中的最后一个测试用例之后立即执行!事实上,它一直等到所有测试用例都被执行,并且 以及TestClass2的类清理

一开始这让我很惊讶,但这显然只是因为我 还没有真正想清楚:既然测试原则上是, 无序,不能保证TestClass1中的所有测试都是 立即连续执行。理论上,执行引擎 可以从TestClass1中选择一个测试用例,然后从TestClass2中选择一个,然后 另一个来自TestClass1,等等。既然是这样,就没有 确保一个测试类中的所有测试都已在之前执行 初始化一个新的测试类,从而初始化所有的类清理方法 也可以推迟到所有测试用例执行完毕


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

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

虽然我会远离这个解决方案,但是如果您没有其他选择,并且无法重构设计以使用提供的生命周期,那么它可能是一个选项。您可以在这里编写自己的基类来计算执行次数,并使用反射来获取测试方法的总量,从而实现自动化。

注意
TestMethod1
TestMethod2
可能会出现故障。我不需要使用TestCleanup。我需要在一个类中的所有测试之后调用ClassCleanup。示例:Class1->ClassInitialize->Test1->Test2->Test3->ClassCleanup->Class2->ClassInitialize->Test4->Test5->Test6->ClassCleanup->Class3…框架似乎不支持它。您必须单独跟踪所有测试,然后在
TestCleanup
中,在所有测试都运行后执行检查和清理。在我看来,用[ClassCleanup/Initialize]修饰的方法应该标记为静态。因为框架实际上为每个测试方法创建了一个新的类实例。静态不会更改实际操作,但它避免了有人认为清理和初始化发生在同一个实例中(仅当只有一个测试时才为真)。这看起来很奇怪,因为命名与实际发生的事情不匹配。谢谢你关于测试顺序的想法!在我的例子中,我只需要在使用自动测试的每个类之后重新启动浏览器,测试顺序中没有依赖项。您可以通过将
runs++
移动到
[TestInitialize]
方法来简化代码。然后,如果您在
[TestCleanup]
中减量
运行
,并检查它是否为
0
,它将支持运行测试的一个子集。@Grinn这将实际导致在第一次测试后立即执行清除逻辑finishes@MarkSegal这是一个公平的观点。也许我写这篇文章时正在运行
async
测试?“(°u o)/”我不知道TestClass1的ClassCleanup在所有测试用例都执行之前不会执行。我想这可能就是为什么我只在TestClass2中看到一个错误,如果我使用TestClass1运行它,而不是单独运行它。很高兴知道。谢谢