How to run ClassCleanup (MSTest) after each class with a test?

I have several classes with test suites.

Each test class begins with ClassInitialize and ends with ClassCleanup. My problem is that ClassCleanup is not called at the end of each class, it is called only after all tests in three classes. Can I fix this problem? Thanks!

[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(); } 
+6
source share
4 answers

Tests are run out of order, including tests between classes. See this blog post:

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

Quote:

Anyway, here is the result from my output window:

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

... this does not mean that TestClass1 ClassCleanup runs immediately after the last test case in the class! In fact, it waits until all test cases have been completed, and runs with TestClass2 ClassCleanup.

At first this surprised me, but it was obvious only because I didn’t really think about it: since the tests, in principle, are disordered, does not guarantee that all tests in TestClass1 are executed in the immediate sequence. Theoretically, the execution engine could select a test case from TestClass1, then one from TestClass2, then another from TestClass1, etc. Since this is the case, there is no guarantee that all tests from the same test class have been completed before the new test class is initialized, and thus all ClassCleanup methods can also be delayed until all test cases have been completed.

Unfortunately, you will have to look for ordered tests or another module testing platform if this does not work for you.

+10
source

I did some tests and used a static field in the class to “tell” the TestCleanup method, which all running methods work. Then you can remove ClassCleanup and do something like this:

 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(); } } 

I would have kept very far from this solution, but if you have no other alternative and you cannot reorganize your design to use the provided life cycle, this may be an option. You could probably love yourself and write your own base class that takes into account execution and gets the total number of test methods, using reflection to automate this material.

+2
source

The usual unittest is "unordered", which means that they can run in any order. You are probably looking for something like a ordered test (see the comment on dominic). An ordered test is a special unittest project. When you run the ordered tests, it will check how you configure them, and test classes to disassemble when they are finished. If the unit test should work fine, then the smell that it experiences interferes with each other. The interference test is unreliable because they fail because the earlier test left some bad data or the test itself failed. You do not know what is really wrong with your code.

+1
source

There is another TestCleanupAttribute attribute that will run after each test.

There is also an attribute to run before each TestInitializeAttribute .

Here is an example of how they work together.

 [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"); } } 

This will lead to

 Running ClassInitialize Running TestInitialize Running TestMethod1..... Running TestCleanup Running TestInitialize Running TestMethod2..... Running TestCleanup Running ClassCleanup 
+1
source

Source: https://habr.com/ru/post/970560/


All Articles