Test method inheritance with NUnit and VS Test Framework

3/28/2009

Today I finished the implementation of the centralized exception handling demo. After adding comments to the code, I wanted to begin the related article. I decided to dedicate a post to one practice, which is test method inheritance.

How to inherit and reuse unit test methods by NUnit and Visual Studio 2008 Unit Testing Framework?

The goal is simple: keep your tests clean and avoid duplicated code.
If I have inheritance in my production code, usualy I have inheritance in my test code as well.

For example, in my application, I have the Person class and I inherit the SpanishPerson and the HungarianPerson classes from this. I don't want to test the Person, because it has only abstract methods, but I want to test the two concrete classes in the same way.


To do this:

  • create a PersonTestBase class, with a _person field with Person type
    create the SpanishPersonTest and HungarianPersonTest classes

  • inherit the SpanishPersonTest and HungarianPersonTest from the PersonTestBase

  • if you are using VS Test Framework, make sure you don't have the [TestClass] attribute on the PersonTestBase, and add the [TestClass] attribute to the two concrete test classes

  • if you are using NUnit, make sure you don't have the [TestFixture] attribute on the PersonTestBase, and add the [TestClass] attribute to the two concrete test classes

  • assign the correct instance to the _person field in the SetUp/TestInitialize methods

  • add generic assertions to the base test class by decorating the methods with [Test]/[TestMethod] attributes


Sorry for the stupid example, I had no better idea :)




Using this pattern you can avoid code duplication in your tests for classes with the same baseclass, and if you want, you can write special (non-generic) test methods in each derived test classes. The code will be cleaner, easier to understand, easier to maintain.
It's a quite easy step to improve the code quality, isn't it?

5 comments:

Moran BD 4/01/2009 5:13 PM  

Why not use a mocking framework for this (like Rhino or Typemock) ? It will make unit testing this easier …

Robert Bonay 4/11/2009 10:24 AM  

Hi Moran BD! The goal was to demonstrate this simple pattern and to "Keep it Short and Simple" :)

Frédéric Legrain 9/29/2010 3:24 PM  

Hi,
I'd like to have inheritance in my test, but I have problems finding a tool to debug inherited tests one by one in Visual Studio.
Do you use specific tools to do it or any other technique?

Jedrek 1/01/2011 4:14 PM  

Well I use NUnit 2.5.8 and the code you wrote doesn't behave nicely. Because instead of two, three tests are run: SpanishPersonTest, HungarianPersonTest and as well PersonTestBase. Of course the first two run correctly, but the third fails with NullReferenceException as _person is set only in derived classes.
It's not a big problem, but I'm curious if it can be fixed somehow (some option, attribute?) not using if-based workarounds.

Yossarian21 1/16/2012 8:03 PM  

Jedrek - I ran into the same problem with 2.5.9 and solved it by putting [TestFixture(Ignore = true)] on the base class. NUnit skips those tests on the base class.