Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force a MSTEST TestMethod to reset all singletons/statics before running?

I'm using MSTEST inside Visual Studio 2008. How can I have each unit test method in a certain test class act as if it were the first test to run so that all global state is reset before running each test? I do not want to explicitly clean up the world using TestInitialize, ClassInitialize, AssemblyInitialize, etc. For example:

[TestClass]
public class MyClassTests
{
    [TestMethod]
    public void Test1()
    {
       // The "Instance" property creates a new instance of "SomeSingleton"
       // if it hasn't been created before.
       var i1 = SomeSingleton.Instance;
       ...
    }
    [TestMethod]
    public void Test2()
    {
       // When I select "Test1" and "Test2" to run, I'd like Test2
       // to have a new AppDomain feel so that the static variable inside
       // of "SomeSingleton" is reset (it was previously set in Test1) on
       // the call to ".Instance"
       var i2 = SomeSingleton.Instance;
       // some code
    }

Although a similar question appeared on this topic, it only clarified that tests do not run in parallel. I realize that tests run serially, but there doesn't seem to be a way to explicitly force a new AppDomain for each method (or something equivalent to clear all state).

Ideally, I'd like to specify this behavior for only a small subset of my unit tests so that I don't have to pay the penalty of a new AppDomain creation for tests that don't care about global state (the vast majority of my tests).

like image 930
Jeff Moser Avatar asked Oct 10 '08 21:10

Jeff Moser


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.

How do I run a MSTest unit test?

To run MSTest unit tests, specify the full path to the MSTest executable (mstest.exe) in the Unit Testing Options dialog. To call this dialog directly from the editor, right-click somewhere in the editor and then click Options.

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.

How do I run MSTest in parallel?

MSTest Configuration By default, MsTest does not run the tests in parallel. Parallelisation must be configured by setting an assembly-level attribute in the SpecFlow project. >Note: SpecFlow does not support scenario level parallelization with MsTest (when scenarios from the same feature execute in parallel).


1 Answers

In the end, I wrote a helper that used AppDomain.CreateDomain and then used reflection to call the unit test under a different AppDomain. It provides the isolation I needed.

This post on MSDN's forums shows how to handle the situation if you only have a few statics that need to be reset. It does mention some options (e.g. using Reflection and PrivateType ).

I continue to welcome any further ideas, especially if I'm missing something obvious about MSTEST.

like image 170
Jeff Moser Avatar answered Sep 29 '22 22:09

Jeff Moser