1

I'm working on a significant number of integration tests in MSTest (100+ for a subsystem), and I really want to group related tests into their own test classes, for readability and because different test groups require different configuration setup.

The tests originally started out with one big test class, that contained static instances of certain services. These services take a while to spin up, and will dominate the test execution time if they are brought up and torn down for each test. The original test code started like this.

[TestClass]
public class IntegrationTests
{
  static ServiceA serviceA = new ServiceA();
  static ServiceB serviceB = new ServiceB();

  [ClassInitialize]
  public static void ClassInit(TestContext context)
  {
    /* Gets the services up and going */
  }
  [TestInitialize]
  public void TestInit()
  {
    /* Gets services back into good states */
  }

  /* Lots and lots of Integration tests */

  [ClassCleanup]
  public static void ClassCleanup()
  {
    /* Tear down the services */
  }
}

The problem with this is different test groups need the services put into different states before the tests are run.

My first idea was to keep the static services in a common base test class, and then create new test classes that inherit from the base class for each test group, like this:

[TestClass]
public class TestClassA : IntegrationTests
{
  /* tests */
}

[TestClass]
public class TestClassB : IntegrationTests
{
  /* tests */
}

[TestClass]
public class TestClassC : IntegrationTests
{
  /* tests */
}

The problem with that is the services get spun up and torn down for each test class. Granted, that's not as bad as them getting created and destroyed for each individual test, but I would like to create them once for each test run.

Is there a way to have separate test classes that all share the same services for integration testing in MSTest?

CHendrix
  • 378
  • 2
  • 12

2 Answers2

1

If I understand your question correctly, you can implement these services using a separate singleton. Something like:

public class Services
{
  static ServiceA _serviceA
  static ServiceB _serviceB
  public static ServiceA InstanceA
  {
    if (_serviceA == null)
      _serviceA = new ServiceA();
    return _serviceA;
  }
  public static ServiceB InstanceB
  {
    if (_serviceB == null)
      _serviceB = new ServiceB();
    return _serviceB;
  }
}

Then this class can be shared by all your test classes.

IProgrammer
  • 321
  • 1
  • 2
  • 8
  • As per usual, I managed to answer my own question before someone else did. The solution was very similar to this. Inside of my test base class, I made a static constructor that handled all of the initialization code. This method would work as well. – CHendrix Mar 28 '16 at 17:01
0

IProgrammer's answer will work, but here's the solution I came up with.

I added a static constructor the the base test class where all of the services are spun up, like so:

[TestClass]
public class IntegrationTests
{
  static ServiceA serviceA = new ServiceA();
  static ServiceB serviceB = new ServiceB();

  //Static constructor gets called once during the lifetime of the appdomain.
  static IntegrationTests()
  {
    /* Gets the services up and going */
  }
  [TestInitialize]
  public void TestInit()
  {
    /* Gets services back into good states */
  }

  /* Lots and lots of Integration tests */
}

Cleaning up the resources after all the tests ran was a little more tricky, since C# does not have static destructors.

However, this answer provided a rather clean and clever workaround.

Here is the "static" destructor code.

private static readonly Destructor Finalise = new Destructor();
private sealed class Destructor
{
  ~Destructor()
  {
    /* Service cleanup code here */
  }
}
Community
  • 1
  • 1
CHendrix
  • 378
  • 2
  • 12