Unit Testing C++ with the Visual Studio Unit Testing Framework
As written in a previous article I was using WinUnit(http://msdn.microsoft.com/en-us/magazine/cc136757.aspx) for my Unit Tests in C++. At this time I was quite happy with the features the framework provided, but as I’m working more and more with it, I was more and more missing the direct integration in the IDE, the Visual Studio Unit Testing Framework provided.
Which is my Unit Testing framework of choice when writing managed code.
The integration in the IDE is really a big plus. Just having to press a key combination [add key combination] and having to run the test again makes a TDD style of programming much more productive and fun. Also debugging the Unit Test involved setting up the test project to use a custom tool for debugging. And than manually having to say “Debug”->”Start new instance” really slowed me down.
So once a day I read a post by Jamie Fristrom from Torpex Games,he had a problem using VSTest for a c++ project. (I sadly couldn’t provide any help). He talked about how easy it is to use unmanaged code with it. I started to try it out myself because, you already know, I like it a lot in managed code.
In the following I want to talk about how to get everything in place to test unmanaged c++ code with VSTest.
Creating a c++ test project
Finding the place where a test project for c++ code can be found, is the first challenge. Normally you would go to “File” –> “New” –> “Project” and there search for “Test Projects”. From here you can create a “Test Project”. But this is just a C# project and there is no way to change it to be a c++ test project.
So what now?
There is a way to create a c++ test project. But it’s a little bit hidden in the menus of Visual Studio.
The only way, I know of, is hidden in the Test Menu of Visual Studio. When you open the Test dropdown menu, you see the option “New Test…”. If you click this you will get the window show below.
In this window you have the possibility to create new Unit Tests. To create a C++ test project you have to open the drop-down menu “Add to Test Project:”
In this menu you have the possibility to add a new test to an existing test project. In my case I have a test project, called “TestProject2”.
But we want to create a new “Visual C++ test project”, so we choose this option. After clicking “OK” we will be asked for a name of the project which will be created.
The project will be created and the UnitTest1.cpp file will be opened. This is our starting point for the newly created project.
The project is ready to be used and will compile. But we have to change the properties for this newly created project a little bit, to make it usable.
Open the properties page for the newly created test project.
Under the general tab, you will find the “Common Language Runtime support” option. This will show, by default, “Safe MSIL Common Language Runtime Support “. This option has to be changed because if this option is set to “Safe …”, we cannot test any unmanaged code not also compiled with “/clr:safe”.
So change this option to “Common Language Runtime Support (/clr)”.
Test C++ code
We got the most work done, now it’s finally time to get c++ code tested.
C++ code, cam be compiled in three different forms, as you already know. It can be compiled as .lib, .dll and .exe
All three forms can be tested using VSTest, but a application(.exe) is more limited.
The table below shows the features support for each type, once when compiled with CLR support and once without.
As you can see just a .exe application doesn’t support stepping into the code. I always try to find the reason a test failed without having to debug, but if i really can’t find the problem I have to recompile the file as a lib.
As I’m talking about, there is one thing you have to do when trying to test code in .exe projects. You have to define the members you want to test with __declspec(dllexport). Like you do when compiling a .dll project. This has to be done, so we can link to the .lib file which will be created now.
Having linked the code, testing is easy. The c++ code can now be used like normal. Just look at the small example below.
Calculator calc;
int result = calc.AddInteger(5,5);
Assert::AreEqual(10, result);
But not everything is that straight forward, when working with c++ strings the hassle begins. If you are using c++ string in your public API’s have a look at http://www.codeproject.com/KB/string/StringConvertor.aspx
I’m new to testing c++ code in VSTest, this article just represents what I have found out and doesn’t have to represent the best way possible to achieve the result. So if you are testing c++ code with VSTest already and you have some tips and improvements I would like to here them.
