Getting TDD in my XNA with NUnit


I’ve had an infatuation with test-driven development (TDD) for years but I’ve never had a chance to use it professionally to any major extent. While the potential benefits of TDD, like reduced bug regression and greater code decoupling, are substantial, the considerable cost involved in learning how to write effective tests and testable code make it a hard-sell to introduce in many work environments.

I can sympathize with a manager who is cautious about adopting TDD, compared to the very palpable up-front costs, the benefits tend to be future-oriented and hard-to-measure. Luckily, I don’t have to worry about convincing managers to let me try TDD for my personal projects. This gives me a chance to give TDD a test-drive (bad pun, I know) and see just how it affects the code I write. Being that I’ve been working a lot with XNA lately, I’ll demonstrate a method to integrate the NUnit unit-testing framework with Visual Studio 2010 Express in order to practice TDD while using XNA.

So, a super brief primer on test-driven development. The main feedback loop in TDD runs roughly as follows:

  1. Write a test
  2. Run your test suite and (presumably) see your new test fail
  3. Write code that will satisfy the test
  4. Run your test suite again and (hopefully) see your new test succeed
  5. Refactor code as needed
  6. Run your test suite to confirm that refactoring hasn’t changed any tested behavior
  7. Brag to a co-worker about doing TDD
  8. Repeat

Given the above workflow, it becomes clear that I should pretty much run tests whenever I change code and build. In that case, it sounds like I should set up my test runner as a post-build step in my Visual Studio solution.

In order to integrate NUnit with Visual Studio, I first download and install NUnit. Then, I create a solution for my new game that looks something like this:

  • MyGame Solution
    • MyGame (an XNA Game project)
    • MyGameLib (an XNA Game Library project)
    • MyGameLibTests (an empty C# project)

I then right-click the projects and tell MyGame and MyGameLibTests to both reference MyGameLib. I will be implementing the majority of my games code in MyGameLib as opposed to MyGame because I want to be able to reference the code in both my test project as well as in the executable itself. Ideally, the MyGame project will contain very little code beyond what is needed to instantiate the code written in MyGameLib and run it as a game.

To actually run the test suite, I open up the property settings for MyGameLibTests and modify the post-build task to run the following:


"C:\Program Files (x86)\NUnit 2.6\bin\nunit-console-x86.exe" /nologo $(TargetFileName)

This will cause Visual Studio to run the command-line version of NUnit and pipe the output into the Build window. If NUnit detects a test failure, it will spit out an error code which will cause Visual Studio to consider the build a failure which will stop me in my tracks until I fix the code so that the test passes (which is what I want.) Because I’m running a 64-bit OS, I need to explicitly tell NUnit to use the 32-bit version of nunit-console since XNA is compiled as 32-bit, hence the x86 in the name of the NUnit executable.

I can run my test suite now but, without tests, that doesn’t mean a whole lot. So, in order to add a little meaning to this whole process, I add a class to MyGameLibTests that looks like ths:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace MyGameLibTests
{
    [TestFixture]
    public class SomeObjectTests
    {
        [SetUp]
        public void Init()
        {
        }

        [TearDown]
        public void Cleanup()
        {
        }

        [Test]
        public void SomeTest()
        {
        }
    }
}

This is pretty much standard NUnit boilerplate code. The [SetUp] and [TearDown] tags mark functions that will be run before and after each test. The [Test] tag marks a test itself. If I go ahead and toss in a test guaranteed to fail like this one:

[Test]
public void SomeTest()
{
    Assert.IsTrue(false);
}

I can build my solution and confirm that the test suite runs and reports a failure. Great! Also, since I will be adding a lot of test files in the future, I went ahead and made a Visual Studio item template (which you can download here) for creating the NUnit boilerplate. I want there to be as little friction as possible between me and writing new tests.

With my test framework in place, I can start writing real failing tests and then the code that makes them succeed. By tying automated testing to my build process, I guarantee that I will run tests whenever I change code. This should help keep me honest by forcing me to fix errors as soon as they crop up.

Now, if you’ll pardon me, I have some code (and tests) to write.

Share this Article:
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Print

One thought on “Getting TDD in my XNA with NUnit

  1. Pingback: Pages from my TDD Diary | Game Dev Without a Cause

Comments are closed.