Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent TestInitialize running for one TestMethod method

I have a set of unit tests that require TestInitialize to run for them to work... however, there is one specific test that i'd love to be able to run without running TestInitialize. Is there a way to do that?

It might look like this:

[TestClass]
public class BingBangBoom
{
    [TestInitialize]
    public void Setup()
    {
        // ...
    }

    [TestMethod]
    public void Bing()
    {
        // ...
    }

    [TestMethod]
    public void Bang()
    {
        // ...
    }

    [TestMethod(PreventInitialize)]
    public void Boom
    {
        // ...
    }
}

No worries if not, I can come up with an alternative solution

Edit - RE DavidG:

It seems a shame to have this:

[TestClass]
public class BingBangBoom
{
    [TestInitialize]
    public void Setup()
    {
        // ...
    }

    // 10 very related methods
}

[TestClass]
public class BingBangBoom2
{
    // 1 method, even though it's entirely related to BingBangBoomin'
}

I guess it is what it is.

like image 285
Jimmyt1988 Avatar asked Mar 15 '17 15:03

Jimmyt1988


People also ask

Does TestInitialize run for each test?

TestInitialize and TestCleanup are ran before and after each test, this is to ensure that no tests are coupled. If you want to run methods before and after ALL tests, decorate relevant methods with the ClassInitialize and ClassCleanup attributes. Save this answer.

What is ClassInitialize?

ClassInitialize runs only on the initialization of the class where the attribute is declared. In other words it won't run for every class. Just for the class that contains the ClassInitialize method. If you want a method that will run once before all tests or classes' initialization use the AssemblyInitialize .

What is ClassInitialize attribute in Mstest?

The method decorated by [ClassInitialize] is called once before running the tests of the class. In some cases, 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.

What is TestInitialize C#?

TestInitialize. This attribute is needed when we want to run a function before execution of a test. For example we want to run the same test 5 times and want to set some property value before running each time. In this scenario we can define one function and decorate the function with a TestInitialize attribute.


1 Answers

That's not immediately obvious, but surely doable.

Assuming you have attribute like this:

public class SkipInitializeAttribute : Attribute { }

The thing you need is public property inside your test class to be injected by testing framework:

public TestContext TestContext { get; set; }

And then just branch your initialization like this:

[TestInitialize]
public void Initialize()
{
    bool skipInitialize = GetType().GetMethod(TestContext.TestName)
        .GetCustomAttributes<SkipInitializeAttribute>().Any();

    if (!skipInitialize)
    {
        // Initialization code here
    }
}

Working sample as self-tested solution:

using System;
using System.Linq;
using System.Reflection;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1
{
    public class SkipInitializeAttribute : Attribute
    {
    }

    [TestClass]
    public class UnitTest1
    {
        public TestContext TestContext { get; set; }

        private bool IsInitializationDone { get; set; }

        [TestInitialize]
        public void Initialize()
        {
            bool skipInitialize = GetType().GetMethod(TestContext.TestName).GetCustomAttributes<SkipInitializeAttribute>().Any();

            if (!skipInitialize)
            {
                // Initialization code here
                IsInitializationDone = true;
            }
        }

        [TestMethod]
        public void TestMethod1()
        {
            Assert.IsTrue(IsInitializationDone);
        }

        [TestMethod]
        [SkipInitialize]
        public void TestMethod2()
        {
            Assert.IsFalse(IsInitializationDone);
        }

        [TestMethod]
        public void TestMethod3()
        {
            Assert.IsTrue(IsInitializationDone);
        }
    }
}

And results:

Starting test execution, please wait...
Passed   TestMethod1
Passed   TestMethod2
Passed   TestMethod3

Total tests: 3. Passed: 3. Failed: 0. Skipped: 0.
Test Run Successful.

Having this general idea in mind you can play with base class / helpers etc.

like image 64
Lanorkin Avatar answered Oct 24 '22 12:10

Lanorkin