I have a base class for my tests which is composed in the following way:
[TestClass] public abstract class MyBaseTest { protected static string myField = ""; [ClassInitialize] public static void ClassInitialize(TestContext context) { // static field initialization myField = "new value"; } }
Now I am trying to create a new test that inherits from the base, with the following signature:
[TestClass] public class MyTest : MyBaseTest { [TestMethod] public void BaseMethod_ShouldHave_FieldInitialized() { Assert.IsTrue(myField == "new value"); } }
The ClassInitialize
is never called by the child tests ... What is the real and correct way of using test initialization with inheritance on 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.
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 .
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.
Unfortunately you cannot achieve this that way because the ClassInitializeAttribute Class cannot be inherited.
An inherited attribute can be used by the sub-classes of the classes that use it. Since the ClassInitializeAttribute
cannot not be inherited, when the MyTest
class is initialized the ClassInitialize
method from the MyBaseTest
class cannot be called.
Try to solve it with another way. A less efficient way is to define again the ClassInitialize
method in MyTest
and just call the base method instead of duplicating the code.
A potential workaround is to define a new class with AssemblyInitializeAttribute
instead. It has a different scope, obviously, but for me it meets my needs (cross-cutting concerns, which just so happen to require exactly the same settings for every test class and test method.)
using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MyTests { [TestClass] public sealed class TestAssemblyInitialize { [AssemblyInitialize] public static void Initialize(TestContext context) { ... } } }
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