Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go about organizing a unit test harness for legacy Visual C++ code?

I have a Visual Studio 2005 C++ project, it is a console application.

I want to start getting bits of the code under a test harness but I've run into some issues that I don't know how to best handle.

I don't want most of my testing code to end up in the normal .exe in production so I thought would be best to create a separate project for my tests. First issue, how is this new project going to call into the rest of the code? Should I make my legacy code a .lib or .dll with a single entry point and create a separate project that calls the main of my legacy code?

Should I go for the ugly hack of putting all my tests in files that are entirely #ifdef TESTING so that the code doesn't end up in my production .exe? If so how should I conditionally load my testing framework? Use a separate Properties Configuration for testing?

I'm basically looking for any suggestions on how to go about getting a test harness on a legacy .exe project in Visual C++

like image 600
thelsdj Avatar asked Jul 21 '09 01:07

thelsdj


1 Answers

First, I'd strongly recommend Michael Feather's book "Working Effectively with Legacy Code". It's all about how to add automated unit tests to a legacy app that has no tests. If you're wondering "how do I even start testing this pile of code" then this book is for you.

Michael is also the author of CppUnit, an Open Source NUnit-like testing framework for C++ code. You can find it here: http://sourceforge.net/projects/cppunit/.

One quick-and-dirty way to add tests is to add a UnitTest configuration to your solution. This configuration would compile your code, but instead of linking it to your main.CPP, you exclude your main.cpp from the build and include UnitTestMain.cpp, where you would place the calls to execute the unit tests. We started out this way a long time ago, when we didn't know any better. You end up spending a lot of time including and excluding all the various testMyCode.cpp modules to the various configurations, though, and it gets tiring after a while. We found that developers didn't like that approach too much.

A much better approach is to add a unit test project to your solution, with a build dependency upon your real project. If the project is named Foo.vcproj, call it Foo_test.vcproj. This project contains just your test code, it #includes your Foo headers, and it links to your compiled fooCode.obj modules. Add a call to execute Foo_test.exe as a post-build step of the Foo_test build, and it automatically runs the unit tests during the build. If any unit tests fail, the build fails. If you have gated-check-ins configured on your build server, nobody can check in changes that break existing tests.

like image 66
John Deters Avatar answered Oct 21 '22 13:10

John Deters