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.
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.
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 .
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With