Recently, I was looking into how to setup a Qt project with unit tests. The Qt-esque way to do this is to use the QTest framework within Qt in order to do this. While not a bad framework, the problem is that there isn’t a good way to integrate it within your project. What I mean with that is that you must link with the QTest library and have a special main() method in order to run the tests. This brings up two problems:
- How do we run the tests if we have only one executable?
- How do we only link with QTest at certain times(e.g. we don’t want to link with QTest when we send the executable out)
Searching for a solution to the problem, one thing that some people did was to create a .pri file with the source files to compile into two projects: one for the main application, and one for the unit tests. The disadvantages to this are that it makes it hard to work with Qt Creator to add in the files, as it can’t add them in automatically to the SOURCES and HEADERS list. So that’s not good.
The other solution that I came across was to add in the files to each project. However, this adds in a lot of overhead, and you must be sure to add in the files to both projects when something changes. So that’s not good either.
The solution that I came up with was to have three separate projects:
- One project for the main code of our project. This gets built as a static library.
- One project to run the main code of our project. This is the normal executable.
- One project to run the unit tests. This links with QTest, and doesn’t get installed by default.
This is basically the same project setup as described here, although it wasn’t until after I had created my project that I realized it was the exact same thing(I did come across the link at first, but didn’t understand it at the time since it wasn’t using QTest).
With this project setup, you can edit the main code in Qt creator, do anything that you want, and still have everything link and test in a clean manner(no need to link with QTest in your main executable!)
The code for the same project is up on github, to give you a general overview of how it all fits together.
Will not build on ubuntu 16.04
Will not build on Windows w/MSVC compiler 2013, 2015 or later
It *WILL* build on Windows using msys/mingw only, which sadly does not meet my needs.
The MainCodeRunner is always FTBFS with unresolved symbols. Tried on a few diff computers to verfiy.
It should be fixed now; the Linux build was a problem with assuming there was a ‘debug’ and ‘release’ folder like on Windows. Windows build should also now work out of the box, it was lacking some extern “C” delarations and it was always assuming MinGW(should now be smart enough to choose either MinGW or MSVC). Thanks!
Is there a possibility that you could show how the project structure works with CMake? I started learning Qt with Qt6 and it was mentioned that it Qt will be slowly moving to CMake rather than qmake.
Perhaps someday I will do that. You can follow the same idea using CMake, making a static library with add_library() for use with unit tests.
This is not strictly related to this at all, but if you want to learn more about testing I would highly recommend watching this presentation: https://www.youtube.com/watch?v=EZ05e7EMOLM&t=1s