Monday, October 12, 2009

NUnit Unit Testing with C++

I switch back and forth between C++ and C#. When doing C# development, NUnit rules the day for unit testing. Whether I'm doing automated tests from the command line or using the GUI to run selective tests (show below in a screenshot from SourceForge) NUnit is a pleasure to use.



If you've ever tried to run unit tests for C++, the landscape is much less appealing. C++ does not have a reflection API, nor does it have attributes that are embedded in the executable code, so it's much more tedious in C++ to do all of the housekeeping to initialize the framework and it's much more difficult to integrate external GUI tools. In short, unit test in C++ is a sub-par experience compared to more modern languages.

But I have good news for you - it's possible to use NUnit with C++. There are two minor caveats:
  1. You must be using Microsoft Visual Studio 2005 or later (sorry MinGW and cygwin users.)
  2. The code to be tested must either be a DLL or a static library. If you need to test code in an .EXE, you should factor that code out into its own static library.
The secret is to place your tests in a separate DLL compiled for C++/CLI, which you enable on the Visual Studio C++ properties page in the General properties, immediately under Configuration Properties. Under Project Defaults, set Common Language Runtime support to "/clr". Don't use any of the other variants - they won't work for this task.

If you haven't built this kind of project before, a C++/CLI project is a curious hybrid that contains all of the power of C++ as well as much of the power of .Net. (Access to certain features, like LINQ, is not available in C++/CLI.)

With a C++/CLI project, you can use NUnit attributes for classes and member functions, just like in C#. When you run NUnit, your target is your test DLL, which implicitly loads either your static library code or your DLL code.

This strategy can also be used in the test environment build into Visual Studio if you have the Professional edition or better.

2 comments:

  1. I have two unmanaged c++ projects in vs2008. One produce a dll, and one produce an exe (command line tool).

    How would you setup a clr dll to test functionality in these projects with NUnit?

    ReplyDelete
  2. There's an article about it on CodeProject (not by me):
    http://www.codeproject.com/KB/cpp/NUnitNativeCPP.aspx

    The explanation is a little terse, but there's some sample code to download that should get you started.

    You cannot use nUnit to test an EXE. The strategy I used was to put the non-UI code in a .lib file (static linking, not DLL), then link that directly to the CLR test DLL for nUnit.

    ReplyDelete