How To Set Up CxxTest

I have been writing unit tests using C#, Java, and Python using MbUnit, JUnit, and PyUnit, respectively. Since C++ does not fully support retrospection, unit testing on C++ can be tricky. Most C++ testing frameworks require the developer to 1) write a test case, then 2) register it — a two step process. This two-step approach carries a couple of problems. First, it is tedious to having write the test case, then register it. Second, the process is error-prone because of potential mismatch between the test case and the registration. In addition, the developer might forgot to register the test case, which exclude the test case from being run.

For those reasons, I like CxxTest for its simplicity: I only need to write the test case and be done with it. At first, I was putting off by CxxTest’s requirement: It relies on Perl or Python to generate registration code. However, I decided to press on and give it a try and the result was worth it.

The following are the steps I performed to get CxxTest working. While they seem a little long, they are not complicated. If you follow them one by one, you should have your system up and running in no time.

Step 1: Installing Perl or Python

I recommend installing ActiveState Python or Perl. Recently, I discovered IronPython, but I do not know if IronPython works with CxxTest or not. After installation, make sure that Python or Perl is in your path.

Step 2: Installing CxxTest

Download CxxTest from its home page. I recommend to unzip CxxTest to the root directory, C:\, but you can pick other locations. After unzipping, add your directory to the PATH and to the INCLUDE environment variables. Here is how to do it in Vista:

  1. Click Start menu, click “Control Panel” from the right column to start the control panel
  2. From the control panel’s search box, type ‘env’ and you will see the choice for “Edit environment variables for you account”, click it.
  3. If the environment PATH does not exist, create it and assign the value C:\CxxTest (or the location of your CxxTest directory). If the PATH evironment already exist, append ;C:\CxxTest to it (note the semicolon which acts as a separator).
  4. Similarly, add C:\CxxTest to the INCLUDE variable
  5. Click OK to submit your changes

Step 3: Create a Test Project

This step is for those who is using Visual Studio. From Visual Studio, create a new project for your test, in my case, I created an empty project and add to it a new file call ‘mytestsuite.h’. This file is where my test cases reside. Please follow the CxxTest’s User Guide for information on how to create your test cases.

I also create a new file call ‘prebuild.cmd’ and add it to the project. The prebuild.cmd file contains only one line:

cxxtestgen –error-print -o mytestsuite.cxx mytestsuite.h

Basically, this script creates the code for registering the test cases. Next, you will configure Visual Studio to run this script before every build:

  1. In Visual Studio, Click the Project menu, then click Properties
  2. In the properties dialog, navigate to the following branch: Configuration Properties > Build Events > Pre-Build Event
  3. Fill in the following information:
    • Command Line = prebuild.cmd
    • Description = Build mytestsuite.cxx
    • Excluded from build = No
  4. Click OK to submit your changes
  5. Run the build once to create the file mytestsuite.cxx
  6. Add this file to your project

Now you have everything setup, each time you build your test project, Visual Studio will launch prebuild.cmd and you will not have to think about it any more, just concentrate on writing your test cases. If you have any question, comment, or correction, please submit them via this blog’s comment.

13 thoughts on “How To Set Up CxxTest

  1. Dan

    Hello Hai, I am very interested in setting up cxxtest for c++ with Visual Studio 2008. I have gotten it working with one project in the solution. However, I want to have one project build the executable and another project test the code, I can’t figure out how to include code from the main project in the testing project. Do you have any tips or examples?

    Thanks a lot,
    Dan

  2. Gail

    Hello Hai,
    Thanks for this blog. I found it very helpful. In order to have the cxxperlgen script run, however, in VC++.NET 2003, I had to add the cxx directory to the Tools->Options->Projects->VC++Directories dialog. Gotta LOVE Microsoft where everything is harder. Even though I am starting my devenv.exe from a shell that has the path setup, this step was still necessary.

  3. Gail

    Please let me restate that last step more precisely:
    In order to have the cxxtestgen script run, however, in VC++.NET 2003, I had to add the CxxTest directory to the Tools->Options->Projects->VC++Directories dialog

  4. Gail

    To get runner.exe to run as a post-build event, build your test using –runner=ParenPrinter. And add a script that calls runner.exe to the Post-Build event. This will dump output to the Build window and let you double click on errors to take you to any failed tests.

    If runner.exe depends on any external DLLs, you will need to set up the PATH in the script since Visual Studio does NOT use environment variables, like %PATH%, added or modified after VS has been installed during a BUILD. (It should be noted however that when running your program in the Debugger from within the IDE, it DOES use updates to the environment in place when the IDE is started.) (The PATH is part of the runtime DLL search order on WINDOWS).

    There are 2 solutions. The better option is to add the necessary env vars and update the path in a batch file that calls runner.exe. For example, place the following in a postbuild.cmd file located with your source code and call it in the Post-Build event:

    set QTDIR=c:\someplace\qt\WINDOWS path = %PATH%;%QTDIR%\debug\lib runner.exe

    The other solution is to add an entry to the VS Tools->Options->Projects->C++ Directories dialog when the the “Show Directories for:” dialog says “Executable Files”. To match the above batch script, the entry would be c:\someplace\qt\WINDOWS\debug\lib.

  5. mojgan

    I’m trying to add the .exe file generated during the build to a batch file (Dos) which runs other automation tests as well. what is the best way to do this? what switches can i use to get a log file? Thanks

  6. Hai Post author

    To mojgan,
    I have not been coding in C++ for about a year now and I cxxtest is no longer in my machine, so I am sorry that I cannot help you out.

  7. Deepthi

    I did everything described. But, an error saying

    ‘prebuild.cmd’ is not recognized as an internal or external command,
    1>operable program or batch file.

    comes up. Can you reckon what would be the problem?

  8. Dean

    Hi Deepthi,

    The problem is that the prebuild.cmd file is listed incorrectly in the blog post.

    If you are using python the prebuild.cmd file should read:

    cxxtestgen.py –error-print -o mytestsuite.cxx mytestsuite.h

    note the *.py extension for cxxtestgen

  9. Pingback: » CXXTest setup in Visual Studio 2010

  10. Farhan Shariff

    Unit test setup — I am using linux platform and using cxxtest framework

    – Note Unit test is carried out on methods and functions and not on main function

    /home/user/Desktop/LTTNG/Prg
    – main.cpp -Num.cpp -num.h

    /home/user/Desktop/LTTNG/Prg/test
    -MyTestSuite1.h

    *main.cpp
    #include
    #include “Num.h”
    #include

    using namespace std;

    int main()
    {
    Num a;
    int add, sub, multi,mod,div;

    add= a.addition (5,3);
    sub= a.subtraction(5,3);
    multi= a.multiplication(5,3);
    div= a.division(5,3);
    mod= a.modulas(5,3);
    cout << "The result of addition " << add << " \n";
    return 0;
    }
    Num.cpp

    #include
    #include “Num.h”
    #include

    using namespace std;

    int main()
    {
    Num a;
    int add, sub, multi,mod,div;

    add= a.addition (5,3);
    sub= a.subtraction(5,3);
    multi= a.multiplication(5,3);
    div= a.division(5,3);
    mod= a.modulas(5,3);
    cout << "The result of addition " << add << " \n";
    return 0;

    }
    root@ubuntu:~/Desktop/LTTNG/Prg# cat Num.cpp
    #include "Num.h"

    int Num::addition(int a, int b)
    {
    int r;
    r=a+b;
    return r;
    }

    int Num::subtraction(int a, int b)
    {
    int r;
    r=a-b;
    return r;
    }
    int Num::multiplication(int a, int b)
    {
    int r;
    r=a*b;
    return r;
    }
    int Num::division(int a, int b)
    {
    int r;
    r=a/b;
    return r;
    }
    int Num::modulas(int a, int b)
    {
    int r;
    r=a%b;
    return r;
    }

    3. Num.h
    #include
    #include “Num.h”
    #include

    using namespace std;

    int main()
    {
    Num a;
    int add, sub, multi,mod,div;

    add= a.addition (5,3);
    sub= a.subtraction(5,3);
    multi= a.multiplication(5,3);
    div= a.division(5,3);
    mod= a.modulas(5,3);
    cout << "The result of addition " << add << " \n";
    return 0;

    }
    root@ubuntu:~/Desktop/LTTNG/Prg# cat Num.cpp
    #include "Num.h"

    int Num::addition(int a, int b)
    {
    int r;
    r=a+b;
    return r;
    }

    int Num::subtraction(int a, int b)
    {
    int r;
    r=a-b;
    return r;
    }
    int Num::multiplication(int a, int b)
    {
    int r;
    r=a*b;
    return r;
    }
    int Num::division(int a, int b)
    {
    int r;
    r=a/b;
    return r;
    }
    int Num::modulas(int a, int b)
    {
    int r;
    r=a%b;
    return r;
    }

    STEP1: Create library (libN1.so in my case ) for Num.cpp

    g++ -Wall -shared -fPIC -o ./libN1.so Num.cpp

    //test folder
    MyTestSuite1.h
    #include
    #include “Num.h”

    class MyTestSuite : public CxxTest::TestSuite
    {
    public:
    void testAddition( void )
    {
    Num n1;
    int a = n1.addition(10,10);
    TS_ASSERT_EQUALS(a,20);
    }

    };

    STEP2: cxxtestgen –error-printer -o runner.cpp MyTestSuite1.h
    //runner.cpp – is the cpp generated

    STEP3: generate executable from the runner.cpp

    g++ -o runner -I /home/user/Desktop/LTTNG/Prg/ -L /home/user/Desktop/LTTNG/Prg/ runner.cpp -lN1

    -I specifies headerfile path- Num.h
    -L specifies library path – libN1.so
    -lN1 specifies libarary name in this case N1 skip lib

    STEP4: set LD_LIBRARY_PATH=/home/user/Desktop/LTTNG/Prg/
    this is the path of the library you created ie. libN1.so

    STEP5 : ./runner
    Running cxxtest tests (1 test). OK!

  11. Hai Post author

    @Sajid, It has been a long time and I have since not using C++ so I can’t answer your question. Please try stackoverflow.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s