Sunday, 11 September 2011

CPP Unit testing with Rational Team Concert

In the spirit of the agile "just enough, just in time" principle, I had originally created the OSLC code sample in a minimalistic way to demonstrate what I was explaining in the posting. As I mentioned in my original post, I did not use method parameters and variables were stuck in to the global variable context.  As it turns out, this is not very unit testable code. 

This is one of the good things about unit testing; it forces one to make the code testable, and by consequence, better structured.  Hence, I have refactored my code to add function parameters and have taken some variables out of the global context. I also fixed up a few other things.

In addition to this I have also broken the code base into three projects (or targets), one of which is the unit test executable. This is necessary as native executables typically only have one entry point, the main (WinMain, _main, etc.) function and I need two (one for the program itself and one for executing the unit tests only).  I could of used command line arguments but this is not a good way of doing it.  It is better practice to not mix unit test code with production code so I basically created projects that produce two executables: one with the unit tests, the other with the production executable (the "main" main function).  The common code used by both I have but in a static library.

In continuation of my previous articles related to C/C++ development on Rational Team concert, i will continue here by adding cppunit unit tests. To start we need to add some things to the MinGW sys environment that I explained in the first posting.  So, if you have not set up MinGW and Rational Team Concert to at least that point, you should do so before continuing.  

There is no better way to understand the code then to show it so lets do some set up and get the code loaded. So lets start being installing MSYS into MinGW.

You will need to do the following:

1.  From within a command prompt type and answer the questions appropriately.
mingw-get intall msys

2. You now need to run a post install script to set up MSYS to work with MinGW.  You now need to launch the MSYS shell and run a post install script. You will need to know where your MinGW installation is (typically C:\MinGW). First launch MSYS and then run the script from the MSYS shell.

3.  We also need the MinGW developer toolkit. You can install it by running the following command from the command prompt.
mingw-get install mingw-developer-toolkit

4. Last thing is to add MSYS to you system path. Do so by adding C:\MinGW\msys\1.0\bin to you system path after the C:|MinGW\bin path entry.

Next step is to install cppunit. We will need to build it as well so we will download the distribution, build it using the MinGW build toolchain. We could also build it using Rational Team Concert but there is really no point to it as we are not developing or contributing to cppunit but rather just using it.  The best thing is to install it into the MinGW directories so that we don't need to add extra include and library paths to our C/C++ projects, we can just keep the default MinGW ones.

You will need to do the following:

1. You need cppunit 1.12.1 from sourceforge.

2. Extract the tar ball into a memorable place. In my case it was C: (C:\cppunit-1.12.1)
3. Open a MSYS shell (C:\MinGW\msys\1.0\msys.bat) and change the directory to the cppunit directory and run the following commands:
cd C:/cppunit-1.12.1
./configure --prefix=/mingw
make install

Thats it! You should now have cppunit installed into your MinGW compiler toolchain environment. Next step is to actually get the code.

1. Download the Rational Team Concert 3.0.1 OLSC sample projects from here. As i mentioned in the opening, I have split the code base into three projects. A common library, the production executable and the unit test executable.

2. Extract the zip file into your Rational Team Concert workspace. (Delete the old ones if necessary)

3. Import the projects into Rational Team Concert by running "File->Import->General->Import Existing Projects" into Workspace

4. Do a search and replace ("Search->File") in the workspace for: servername, 9443, username, password and replace them with your corresponding rational team concert host name, port, username and password (for an JazzAdmins user preferably).

5. You will also need to adjust some paths in the build.xml files and make files in all the projects. If you do not remember which ones please look at the blog posting about setting up static analysis (the CLASSPATH and JAVA variables in the Makefiles and the path to RSAR in build.xml). If you do not want static analysis as part of the build you can comment the corresponding lines out.
You should be able to build after doing the proper adjustments. You will notice that the builds are using the MinGW make tool and generating make files. This seems to work the best with Rational Team Concert and CDT. It also provides the added benefit of easily testing Makefiles by simply switching the "Generate Makefiles Automatically" option in the "Project Properties->C/C++ Build" section.

Keys things to note here is the refactoring that has been doing to the project and build environments:
  • Three Projects:
    • OSLC Consumer: The Production executable
    • OSLC Consumer Common: A static library used by the executables
    • Test OSLS Consumer: The unit test executable that runs the unit tests
  • Three makefiles and build.xml files:
    • OSLC Consumer
      • JBEMakefile builds the production exe and runs static analysis on OSLC Consumer (OSLCConsumer.exe) and also kicks off the other project makefiles as a precondition. It is used directly by the JBE (Jazz Build Engine).
      • build.xml provides updates to JBE about the build and published static analysis links an artifacts.
    • OSLC Consumer Common:
      • Makefile builds the static libary (libOSLCConsumerCommon.a) and runs static analysis on it.
      • build.xml provides updates to JBE about the build and published static analysis links an artifacts.
    •  Test OSLC Consumer:
      • Makefile builds the test executable (TestOSLCConsumer.exe) ,runs static analysis on it, and runs the executable (ignoring errors as the executable publishes results to xml).
      •  build.xml provides updates to JBE about the build and published static analysis links an artifacts. It also publishes the xml unit test results to JBE using the cppunitLogPublisher tag.
The build engine definition remains unchanged from previous blogs. The only thing to do is to deliver the code into the RTC SCM, accept it into the Build Stream and request a build as described in previous blogs.

The end result you should see a build result like this:

You can see that 2 unit test were run ant they both succeeded. You can try to make the unit test fail on purpose by modifying the code to see what happens. You can also see the static analysis artifacts and links.
I you actually take a look at the test you can see that the results have been published:

So, we have no build a complete template C/C++ software development environment in Rational Team Concert 3.0.1.

I am not sure what I should cover in subsequent blogs regarding this topic but I am open to suggestions!