A: 

Just a thought, but you could perhaps create an ordered test and add the same tests twice: add all tests once, then all tests again in the same order. In your test context keep a count of the number of times each test has been run. I believe that the context is static so it should only be created once, then reused as more tests are run. In the test set up, use the XmlStorageManager if the test count is even and the DbStorageManager if the test count for that test is odd.

tvanfosson
+5  A: 

I'm not an MSTest user, but you probably have a few options. Normally with NUnit I'd use a generic or parametrised fixture, but I'm not sure whether MSTest has similar capabilities. In light of this, here's how I'd do this with NUnit, in a form that should be reproducible using any unit test framework via the template method pattern.

Steps:

  • Define an abstract base class with all of the tests in it
  • Put in an abstract method called CreateStorageManager() that returns an IStorageManager (or whatever interface the two dependencies implement)
  • Subclass the fixture twice and provide an implementation of CreateStorageManager() that returns the concrete type you wish to use to run the tests.

Here's the code for the equivalent NUnit version; I'm sure you can extrapolate. Note: The inheritance rules for MSTest may differ slightly from what I'm used to. If it doesn't work, you could try marking the base class as a test fixture.

public abstract class PasswordManagerFixtureBase
{
     protected abstract IStorageManager CreateStorageManager();

     // all tests go in this fixture
     [Test]
     public void SomeTestOrOther()
     { 
         var passwordManager = CreatePasswordManager();

         // do test logic

     }

     private PasswordManager CreatePasswordManager()
     { 
          // calls into subclass implementation to get instance of storage
          IStorageManager storage = CreateStorageManager();
          return new PasswordManager(storage);
     }   
}

// Runs the tests in the fixture base using XmlStorageManager
[TestFixture]
public class PasswordManager_XMLStorageManagerImplTests
{
      protected override IStorageManager CreateStorageManager()
      {
          return new XMLStorageManager();
      }
}

// Runs the tests in the fixture base using DbStorageManager
[TestFixture]
public class PasswordManager_DbStorageManagerImplTests
{
      protected override IStorageManager CreateStorageManager()
      {
          return new DbStorageManager();
      }
}

There may be a more elegant way to do this with MSTest, but this should work.

Mark Simpson
This should be the right approach, but the tests from the base class do not run.
Dabblernl
Try marking the base class as a test fixture and see if that works :oIt was always a possibility that the inheritance rules in MSTest differs from NUnit as even NUnit itself has changed its behaviour between releases.
Mark Simpson
I simply added the abstract keyword before the original tests and then let VS construct a new empty testclass,which I then made inherit the base class. That should have the effect that the tests in the base class run. But they don't. What I can do now is of course calling the tests by using base.Test1() etc. That does save some space, but is of course still copying and pasting.
Dabblernl
I have use something along these lines in the past and it worked, but I can't remember the details.
Ian Ringrose
TrueWill
@True Will: In Nunit it may very well work, but I want to know if it works in the visual studio testframework
Dabblernl
+1  A: 

If a PasswordManager has a dependency like IStorageManager which is being injected (DI, IoC, etc.) then it could be enough to mock this interface instead of using concrete implementation so there is no need to test PasswordManager for both XML and Db realizations which could be tested separately from PasswordManager.

dh
Thanks, that is how it is done in pure unit tests. I am still interested to test it as I asked.
Dabblernl