New project structure for projects in Qt Creator with unit tests

Note: This is a new version of an earlier post, with a revised project structure.

Note 2: See this post for the same project structure using the even better Catch testing framework.

This post assumes that you are using a C++ testing framework such as UnitTest++. See this earlier post for some information on installing UnitTest++ on Ubuntu.

To get the most out UnitTest++ it is a good idea to integrate its output into the Qt Creator IDE. The way I have set this up in Qt Creator is with subprojects. One for the main project, which again is split into the app itself and a library, and one for the tests. In addition, I have a helper project file, named defaults.pri. The structure of the project is like this:

MyProject
├─ MyProject.pro
├─ defaults.pri
├─ app/
│  ├─ app.pro
│  └─ main.cpp
├─ src/
│  ├─ src.pro
│  └─ myclass.cpp
└─ tests/
   ├─ tests.pro
   └─ main.cpp

An example project using this code structure has been posted on Github by Filip Sund. (Thanks to Filip for doing this!)

The main project file, MyProject.pro will now be based on a subdirs template, and may look like this:

TEMPLATE = subdirs
CONFIG+=ordered
SUBDIRS = \
    src \
    app \
    tests
app.depends = src
tests.depends = src

The app.depends and tests.depends statements makes sure that the src project is compiled before the application and tests, because the src directory contains the library that will be used by both the app and the tests.

(Thanks to Will for noting that this works better for parallel builds with make -j 8 than my previous version only using CONFIG+=ordered. We should keep CONFIG+=ordered in there still, though, because depends doesn’t affect the order when using make install).

defaults.pri

Each of the other .pro files will include defaults.pri to have all the headers available. defaults.pri contains the following:

INCLUDEPATH += $$PWD/src
SRC_DIR = $$PWD

If the library, main program and tests use common libraries, it is very useful to have the defaults.pri define these dependencies too.

./src

In the src folder, I have myclass.cpp, which is the class that I want to use and test. The src.pro needs to compile to a library, so that it may be used both by app and tests, and could look something like this:

include(../defaults.pri)
CONFIG -= qt

TARGET = myapp
TEMPLATE = lib

SOURCES += myclass.cpp
HEADERS += myclass.h

What this class does is not so interesting, it could be anything. A simple example could be this header file:

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass {
public:
    double addition(double a, double b);
};

#endif // MYCLASS_H

With this accompaning source file:

#include "myclass.h"

double MyClass::addition(double a, double b) {
    return a * b;
}

./app

I only have a main.cpp file in app, because the app is basically just something that uses everything in the src folder. It will depend on the shared compiled library from src, and app.pro would look something like this:

include(../defaults.pri)

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp

LIBS += -L../src -lmyapp

The main.cpp file could be a simple program that uses MyClass:

#include <myclass.h>
#include <iostream>

using namespace std;

int main()
{
    MyClass adder;
    cout << adder.addition(10, 20) << endl;
    return 0;
}

./tests

In the tests folder I have simply added a main.cpp which will run the tests. Then tests.pro has the following contents:

include(../defaults.pri)
TEMPLATE = app

CONFIG   += console
CONFIG   -= app_bundle
CONFIG   -= qt

SOURCES += main.cpp

LIBS += -lunittest++ -L../src -lmyapp

Which now links to the myapp library in addition to the unit tests.

The main.cpp in tests file which could contain the following, if we were to use UnitTest++ as our testing library:

#include <unittest++/UnitTest++.h>
#include <myclass.h>

TEST(MyMath) {
    MyClass my;
    CHECK(my.addition(3,4) == 7);
}

int main()
{
    return UnitTest::RunAllTests();
}

This test will fail because my implementation of MyClass::addition is completely wrong:

class MyClass {
public:
    double addition(double a, double b) {
        return a * b;
    }
};

Note that I’m including MyClass by through <myclass.h> which is possible because of the INCLUDEPATH variable in defaults.pri.

This is hopefully all you’ll need to define a project that compiles a library, as well as tests and an application using the library.

Published by

Svenn-Arne Dragly

I'm a physicist and programmer, writing about the stuff I figure out as I go.

11 thoughts on “New project structure for projects in Qt Creator with unit tests”

    1. Thanks for the heads up! I will definitely do some tests and see if it works for me too. I too have had problems with multicore builds. I just started living with the fact that I had to build some projects twice to make sure multicore builds succeded.

      However, it bugs me that the “depends” variant won’t work on platforms that don’t use makefiles. Do you happen to know what platforms may be affected?

      1. hi, could sent all the project file to me?
        I want to learn New project structure for projects in Qt Creator with unit tests.May I ? thank you!

  1. So far, I’ve only made significant use of subdirs builds on very ordinary Linux, so I can’t actually speak to platforms with different build backends. (Though, I do need to move a project to Windows in the nearish future, so I’ll probably need to do some tinkering with my build.) At the moment, I am building 5 small shared libs, with an application and a bunch of tests that depend on the libs, and it all seems to be working great without “ordered.” My builds are currently quick enough that I haven’t actually done any analysis to prove that parallel building is actually working, but I think it is distributing the build effectively. (If it wasn’t working, it would probably have been slow enough to annoy me into checking on that sort of thing…)

    1. Just tested it now, and it seems to work flawlessly in a medium size project I’ve got. It takes about 2 minutes to build with just “make”, and about 30 seconds with “make -j 8” on a hyperthreaded quad-core machine. It appears that the depends property does the job and ensures everything is built in order. So parallel building is definitely working.

      Again, thanks for the tip. I’ll update the blog post now to reflect the change.

    1. This setup makes two executables: one for the app and one for the tests. That’s why you need to build src as a library that can be used by both. You cannot link the tests against the executable app file. And with qmake, this is most easily solved by putting app, src and tests in separate subdirs.

      Another option is to have a common .pri file and build all the cpp files two times. Once for the app and once for the tests. In this case I believe the build time can be reduced if you share the .o files between app and tests.

Leave a Reply