Categorized | Code

Organizing test classes

sorted_by_category

VS2012 Test Explorer: Tests sorted by test category

 

Recently I switched from using NUnit to MSTest. The main reason  was that I wanted to be able to use the Test Explorer in Visual Studio 2012. If I had managed get the  NUnit Test Adapter for Visual Studio to work I’d probably would have continued to use NUnit but it’s good to learn something new :)

Why it didn’t work I don’t know, possibly my computer setup that already had a few hiccups. Anyway, to the subject at hand…  Organizing unit tests….

There’s a few differences that you got to keep in mind when you decide to organize tests so in code I’ll be setting up for MSTest but there are equivalents for NUnit, or any other framework you choose.

Test Explorer tests sorted by outcome

Test Explorer tests sorted by outcome

The way I like to do it is to group my tests. Firstly I place all tests that belong to a Class in the same TestClass. All tests for UserAccountRepository is found in the TestClass UserAccountRepositoryTests. Secondly I categorize all tests with [TestCategory("categoryname")].  The category names I use is in form of “ClassNameUnderTest.TestMethod”. In the VS 2012 Test Explorer you’ll get a nice overview of your tests where you can easily navigate your way around tests. As for documentation you quickly see what UserAccountRepository is supposed to do but this view isn’t very good for running tests because it’s hard to see what tests failed and what tests passed.

Sort your tests by outcome to get a plain list of the test results. You can also sort tests by time it takes to run them to identify what tests that are very resource intensive.

Since I place all tests Class tests in a single Test Class I also create some global variables that is used by my tests. There are two different setup and tear-down modes. One that run before all tests, and one that is executed for each test in your  test class. In this post I’ll show you how I use the class initialize and clean up/teardown.

The first one, the class initializer (much like a constructor)  for MSTest looks like this:

[ClassInitialize]
public static void Init(TestContext context)
{
    // class initialization code goes here
}

The method can be named anything you want, but it have to be static, public, does not return a value and should take a single parameter of type TestContext.

The second method is the class cleanup (destructor) method that looks like this:

[ClassCleanup]
public static void Dispose()
{
    // cleanup code here
}

This too has to be static, public and have no return value. It takes no parameters.

These two methods can be used to initialize global variables and release them.

From my first Entity Framework Unit Test post you can see that I declared the fakeUserAccountEntityDbSet and the repository I was testing directly in the test method. The better way of doing it is to declare this in the ClassInitialize method, It saves time and makes for cleaner code.

The actual implementation I use is more like this:

[TestClass]
public sealed class UserAccountRepositoryTests
{
   private static  UserAccountRepository repository = null;
   private static DbSet fakeUserProfileEntityDbSet = null;

   [ClassInitialize]
   public static void Init(TestContext context)
   {
      repository = new UserAccountRepository();
      fakeUserAccountEntityDbSet =
           Isolate.Fake.Instance<dbset>();
   }

   [ClassCleanup]
   public static void Dispose()
   {
      fakeUserAccountEntityDbSet = null;
      repository = null;
   }
}

In the Init method I creates the repository I am testing against, and creates the fake Entity DbSet object using Typemock Isolator.

The test method already looks a lot cleaner containing only local test code.

[TestMethod]
[Isolated]
public void GetUserAccountWithToken_CorrectToken_ReturnUserId()
{
   string aToken = Guid.NewGuid().ToString();
   int fakeUserId = -1;
   var user = new useraccount()
                  {
                   id = fakeUserId , 
                   appToken = aToken 
                  };

Isolate.WhenCalled(
             () => fakeUserAccountEntityDbSet.Single(null))
                                     .WillReturn(user);

   Assert.AreEqual(-1, 
                       repository.GetUserAccountWithToken(correctToken));
}

The only thing I need to declare in my test now is “local” data  needed to do this specific test, here it is a fake token, fake user id and the faked useraccount object I want Typemock to give me as a replacement for the real useraccount from the database.

The other two methods you can use is the ones that run before and after each individual test, declared like this:

[TestInitialize]
public void SetUp()
{
 // test resource initialize
} 
[TestCleanup]
public void TearDown()
{
 // test resource release
}

If all your tests needed a useraccount object you declare the object as a global, then initialize it in the TestInitialize method and releases the resources you used in the TestCleanup. This can save you a lot of time when you are writing tests but remember that this runs for each and every test in your test class.

Use Facebook to Comment on this Post

One Response to “Organizing test classes”

Trackbacks/Pingbacks

  1. [...] In this post I’ll have two classes, and an Interface. All test code that uses references to Typemock Isolator is what you would typically place in the Arrange part of your AAA (Arrange-Act-Assert) test and/or place it into class or test initialization. [...]


Google Translate

EnglishFrenchGermanItalianPortugueseRussianSpanish

Blog Traffic

Hits

Pages|Hits |Unique

  • Last 24 hours: 2,149
  • Last 7 days: 12,976
  • Last 30 days: 48,816
  • Online now: 6

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

%d bloggers like this: