Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MsTest ClassInitialize and Inheritance

Tags:

c#

mstest

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?

like image 219
Raffaeu Avatar asked Apr 11 '13 08:04

Raffaeu


People also ask

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 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 .

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.


2 Answers

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.

like image 93
chaliasos Avatar answered Sep 19 '22 21:09

chaliasos


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)     {       ...     }   } } 
like image 20
Dave Sexton Avatar answered Sep 21 '22 21:09

Dave Sexton