MSTest v2: Test lifecycle attributes

This post is part of the serie 'MSTest v2'. Be sure to check out the rest of the blog posts of the serie!

In a test project, some tests may have pre-conditions. You may also do some cleanup. For instance, you need to set a global configuration, or to delete some files after a test ran. This may be more useful for integration tests than for unit tests.

MSTest v2 provides a way to declare methods to be called by the test runner before or after running a test. Here's how to use declare them:

Initialize/Cleanup by assembly

The method decorated by [AssemblyInitialize] is called once before running the tests of the assembly. The method decorated by [AssemblyCleanup] is called after all tests of the assembly are executed. These methods can be located in any class as long as the class is decorated by [TestClass].

[TestClass]
public class Initialize
{
    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext context)
    {
        Console.WriteLine("AssemblyInitialize");
    }

    [AssemblyCleanup]
    public static void AssemblyCleanup()
    {
        Console.WriteLine("AssemblyCleanup");
    }
}

Initialize/Cleanup by class

The method decorated by [ClassInitialize] is called once before running the tests of the class. In some case, you can write the code in the constructor of the class. The method decorated by [ClassCleanup] is called after all tests from all classes are executed.

[TestClass]
public class TestClass1
{
    [ClassInitialize]
    public static void ClassInitialize(TestContext context)
    {
        Console.WriteLine("ClassInitialize");
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
        Console.WriteLine("ClassCleanup");
    }

    [TestMethod]
    public void Test1()
    {
    }
}

Initialize/Cleanup by test

The method decorated by [TestInitialize] is called before running each test of the class. The method decorated by [TestCleanup] is called after running each test of the class.

[TestClass]
public class TestClass1
{
    [TestInitialize]
    public void TestInitialize()
    {
        Console.WriteLine("TestInitialize");
    }

    [TestCleanup]
    public void TestCleanup()
    {
        Console.WriteLine("TestCleanup");
    }

    [TestMethod]
    public void Test1()
    {
    }
}

Execution log

Here's the execution log. I think this is much more clearer than long sentenses!

AssemblyInitialize (once by assembly)
  Class1Initialize (once by class)
    TestInitialize (before each test of the class)
      Test1
    TestCleanup    (after each test of the class)
    TestInitialize
      Test2
    TestCleanup
    ...
  Class2Initialize
      ...
  Class1Cleanup    (once by class)
  Class2Cleanup
AssemblyCleanup    (once by assembly)

Comments

Kamil Jaworski -

"The method decorated by [ClassCleanup] is called after all tests of the class are executed."

This is not true. ClassCleanup methods run after all tests from all classes finish.

Meziantou -

You are right! I'll fix that.

Thanks

Leave a reply