3

How to configure the order of execution of SQL Server Unit Tests?

So for example I have this structure

UnitTests          -- Main Project
  - FooSchema      -- Test Class
     - SprocFoo1   -- Individual Unit Tests / Test Methods 
     - SprocFoo2
  - BarSchema
     - SprocBar1
     - SprocBar2

The Test Run like this sometimes:

 -- Test Initialiaze for TestClass FooSchema
    -- Pre-Test   -- for SprocFoo1
    -- Test       -- for SprocFoo1
    -- Post-Test  -- for SprocFoo1
    -- Pre-Test   -- for SprocFoo2
    -- Test       -- for SprocFoo2
    -- Post-Test  -- for SprocFoo2
 -- Test Cleanup for TestClass FooSchema
 -- Test Initialiaze for TestClass BarSchema
    -- Pre-Test   -- for SprocBar1
    -- Test       -- for SprocBar1
    -- Post-Test  -- for SprocBar1
    -- Pre-Test   -- for SprocBar2
    -- Test       -- for SprocBar2
    -- Post-Test  -- for SprocBar2
 -- Test Cleanup for TestClass BarSchema

and sometimes like this:

 -- Test Initialiaze for TestClass BarSchema
    -- Pre-Test   -- for SprocBar1
    -- Test       -- for SprocBar1
    -- Post-Test  -- for SprocBar1
    -- Pre-Test   -- for SprocBar2
    -- Test       -- for SprocBar2
    -- Post-Test  -- for SprocBar2
 -- Test Cleanup for TestClass BarSchema
 -- Test Initialiaze for TestClass FooSchema
    -- Pre-Test   -- for SprocFoo1
    -- Test       -- for SprocFoo1
    -- Post-Test  -- for SprocFoo1
    -- Pre-Test   -- for SprocFoo2
    -- Test       -- for SprocFoo2
    -- Post-Test  -- for SprocFoo2
 -- Test Cleanup for TestClass FooSchema

How could I setup that the FooSchema always runs first?

Karlx Swanovski
  • 2,869
  • 9
  • 34
  • 67

2 Answers2

1

I am not into this specific topic (SQL Server), but the whole point of unittesting is that a unittest should always stand on it's own: that is, without any dependencies (or at least as minimal as possible). Because of this I believe you cannot change the order in which the unittests run, simply because that shouldn't be necesarry in the first place.

So if your BarSchema unittests have a dependency on the FooSchema unittests, you would probably be better of to redo your BarSchema unittests.

vrijdenker
  • 1,371
  • 1
  • 12
  • 25
0

The SQL Server Unit Tests are common MSUnit test classes.

The first option is to use a MSUnit Ordered Test. It is a special item in Visual Studio with a designer that allows you to specify the exact order of your SQL Server Test methods (or any other MSUnit test).

You can right click on your Visual Studio test project and add an Ordered Test in two clicks.

Ordered tests are good if you want a designer to maintain the order of your tests, and if you want to keep the test classes isolated, which is more maintainable.

In case you don't like Ordered Tests and want more control, then you can use "MSUnit test nesting" and contain all your MSUnit tests in a root container Test Class:

[TestClass]
public class RootContainer
{
    [TestClass]
    public class NestedFooSchemaTestClass
    {
        [ClassInitialize()]
        public static void ClassInit(TestContext context)
        {
            Debug.WriteLine("-- Test Initialize for TestClass FooSchema");
        }

        [TestInitialize()]
        public void TestInitialize()
        {
            Debug.WriteLine("  -- Pre-Test");
        }

        [TestMethod]
        public void Test1InClass()
        {
            Debug.WriteLine("  -- Test");
            Assert.AreEqual(true, true);
        }

        [TestMethod]
        public void Test2InClass()
        {
            Debug.WriteLine("  -- Test");
            Assert.AreEqual(true, true);
        }

        [TestCleanup()]
        public void TestCleanup()
        {
            Debug.WriteLine("  -- Post-Test");
        }

        [ClassCleanup()]
        public static void ClassCleanup()
        {
            Debug.WriteLine("-- Test Cleanup for TestClass FooSchema");
        }
    }

    [TestClass]
    public class NestedBarSchemaTestClass
    {
        [ClassInitialize()]
        public void ClassInit(TestContext context)
        {
            Debug.WriteLine("-- Test Initialize for TestClass BarSchema");
        }

        [TestInitialize()]
        public void TestInitialize()
        {
            Debug.WriteLine("  -- Pre-Test");
        }

        [TestMethod]
        public void Test1InClass()
        {
            Debug.WriteLine("  -- Test");
            Assert.AreEqual(true, true);
        }

        [TestCleanup()]
        public void TestCleanup()
        {
            Debug.WriteLine("  -- Post-Test");
        }

        [ClassCleanup()]
        public void ClassCleanup()
        {
            Debug.WriteLine("-- Test Cleanup for TestClass BarSchema");
        }
    }
}

When you run this code you get:

-- Test Initialize for TestClass FooSchema
   -- Pre-Test
   -- Test
   -- Post-Test
   -- Pre-Test
   -- Test
   -- Post-Test
-- Test Initialize for TestClass BarSchema
   -- Pre-Test
   -- Test
   -- Post-Test
-- Test Cleanup for TestClass FooSchema
-- Test Cleanup for TestClass BarSchema

The order is almost as you want it. The only difference is that the Test Cleanup for the classes will run as a batch at the end. This is because the Test Classes are bulk unloaded after all tests finish running, and that's why it is not possible to control the exact time when Cleanup is executed. This is intentional, since tests are supposed to be isolated.

If you still want full control over the execution an alternative approach would be to run your tests via a custom script that uses MSTest command line utitilites.

Faris Zacina
  • 14,056
  • 7
  • 62
  • 75