Search code examples
c++qtunit-testing

Where exactly do I put QTEST_MAIN?


I wanted to add some unit tests to an existent Qt application, but I can't figure out how to do it.

The official documentation explains it, telling that I need to create a class containing the test code (I suppose that both the class itself and its implementation belong to the same file?) Then, the documentation states:

Finally, to make our test case a stand-alone executable, the following two lines are needed:

QTEST_MAIN(TestQString)
#include "testqstring.moc"

Do I have to add it in the same file which contains the test code? Or do I have to create some other file? Or maybe I am supposed to put it in the exising main.cpp?

Another official documentation seems even more cryptic regarding QTEST_MAIN:

Finally, if the test class has a static public void initMain() method, it is called by the QTEST_MAIN macros before the QApplication object is instantiated. This was added in 5.14.

In their example, however, there is no initMain method. Do I need to add one? And, anyway, what should I do with the actual QTEST_MAIN macro?


Solution

  • It looks like:

    1. QTEST_MAIN replaces the main function. Essentially, the answer to my original question is to throw the existing main and put QTEST_MAIN instead. It compiles and, when ran, executes the tests.

    2. It runs only a single class (!), and “the proper way is to have [one] test project per test class.” (!) (source)

    3. There is a QTest::qExec function that can be called instead of using QTEST_MAIN—one can call it from within an existing main. However, one call is still matching one test class, and the function “shall not be called more than once.” (source)

    A more “standard” way of doing tests would be, therefore, to move to a more mature testing framework, such as GTest. What I didn't know is that including Qt in a GTest project is very easy. One has to add:

    find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
    

    and:

    target_link_libraries(... Qt6::Core Qt6::Gui Qt6::Widgets)
    

    to CMakeLists.txt, and that's pretty much all that's needed.