views:

27

answers:

1

I though the whole purpose of these attributes was to run them only once per assembly. I have a simple class as follows:

[TestClass]
public class AssemblyIntegrationTestSetup
{
    public AssemblyIntegrationTestSetup() { }
    public TestContext TestContext { get; set; }

    [AssemblyInitialize]
    public static void SetupIntegrationTests(TestContext context)
    {
         WindowsServiceService.Instance.StartService("Distributed Transaction Coordinator");
    }

    [AssemblyCleanup]
    public static void TeardownIntegrationTests()
    {
          WindowsServiceService.Instance.StopService("Distributed Transaction Coordinator");
    }

}

However when I run the test suite the assembly-level Initialize and Cleanup methods execute twice. Here are the details about my environemnt:

  1. All test classes are in the same project/assembly.
  2. I have integration and unit tests separated by namespace.
  3. For the integration tests, I am using MSTextExtensions to allow for rollback on database transactions.
  4. I am also starting/stopping the MS SQL Server DTC service, which is required for the rollback ability. I wanted to do this once per test suite run (and the best compromise I found was to use the Assembly-level attributes). The code will work, but it executes twice.
  5. If it matters, I'm using also the Microsoft Moles Framework in some of my tests.

The observed behavior is similar to:

AssemblyInitialize         

Class1.TestInitialize
Class1.TestMethod1
Class1.TestCleanup

AssemblyInitalize         <-- //This shouldn't be happening right?

Class2.TestInitialize
Class2.TestMethod1
Class2.TestCleanup

Class2.TestInitialize
Class2.TestMethod2
Class2.TestCleanup

Class5.TestInitialize
Class5.TestMethod1
Class5.TestCleanup

Class7.TestInitialize
Class7.TestMethod1
Class7.TestCleanup

//More random bouncing around then...

AssemblyCleanup 
AssemblyCleanup           <-- //This shouldn't be happening right?
A: 

From the MSDN Library article:

Important

This attribute should not be used on ASP.NET unit tests, that is, any test with [HostType("ASP.NET")] attribute. Because of the stateless nature of IIS and ASP.NET, a method decorated with this attribute might be called more than once per test run.


There are few knobs you can tweak in test runner. I would just punt the problem with a counter:

private int InitCount;

[AssemblyInitialize]
public static void SetupIntegrationTests(TestContext context)
{
     if (InitCount++ == 0) {
         WindowsServiceService.Instance.StartService("Distributed Transaction Coordinator");
     }
}

[AssemblyCleanup]
public static void TeardownIntegrationTests()
{
      if (--InitCount == 0) {
          WindowsServiceService.Instance.StopService("Distributed Transaction Coordinator");
      }
}
Hans Passant
Matt Spinelli
@Matt - post updated.
Hans Passant