I got my Qt project and I\'m using Qt Creator. I want to unit-test all my code.
However I\'m quite new at QTestLib framework but everyone recommended it for testing Qt-b
First structure source like below:
MyApp
MyAppUnitTest
Under MyApp
project, use a MyAppSrc.pri
to locate source files:
SOURCES += \
../../../framework/src/myapp.cpp \
../../../framework/src/mycontrol.cpp
HEADERS += \
../../../framework/inc/myapp.h \
../../../framework/inc/mycontrol.h
INCLUDEPATH += ../../../framework/extlibs
Include this .pri
in MyApp.pro
like:
include(MyAppSrc.pri)
Then structure the testing project exactly like the main project, with one extra include in MyAppUnitTest.pro
:
include(MyAppUnitTestSrc.pri)
include(../MyApp/MyAppSrc.pri)
I like the other answers but I would like to also give some feedback how we do this at the company I currently work for:
Create a subdirs
project (this will be the top-level project that will manage ALL including your library project or whatever you want to test)
+-----MyProject (top-level subdirs)
Add your library projects as a sub-project
+-----MyProject (top-level subdirs)
|
+-----Library (library project, UI project etc.)
Add another subdirs
projects (for the tests)
+-----MyProject (top-level subdirs)
|
+-----Library (library project, UI project etc.)
|
+-----Tests (subdirs for tests)
Create a QUnitTest
project an add it to the testing subdirs
project
+-----MyProject (subdirs)
|
+-----Library (library project, UI project etc.)
|
+-----Tests (subdirs for tests)
|
+----- TestA (QUnitTest project for testing feature A)
Add as many tests as you see fit
...
|
+-----Tests (subdirs for test)
|
+----- TestA (QUnitTest project for testing feature A)
|
+----- TestB (QUnitTest project for testing feature B)
|
+----- TestC (QUnitTest project for testing feature C)
|
...
|
+----- TestZ (QUnitTest project for testing feature Z)
If you need to group test in groups you can also use subdirs
to do that. subdirs
also ensures creating of real directories in your file system. If you want to avoid too much subdirs
ing you can group the tests in folders that you have created on your own in your filesystem inside the Tests
project folder.
Beside that I would also recommend to add a subdirs
for template projects.
+-----MyProject (subdirs)
|
+-----Library (library project, UI project etc.)
|
+-----Tests (subdirs for tests)
| |
| ...
|
+-----Templates (subdirs for template projects
|
+----- TemplateA (template project for feature A)
|
+----- TemplateB (template project for feature B)
|
+----- TemplateAB (template project for feature A and B together)
|
...
|
+----- TemplateZ (template project for feature Z)
This is of course based on your library's functionality. With template projects I mean custom widgets etc. that link against your library and expose selectively (or all) of its functionality in the way it's supposed to appear to the user. For example if you have a library that manages various camera devices you can create a template project for each camera device thus allowing for the users of your library to just copy-paste the specific template project and expand it or at least see how the integration of your library is supposed to happen in general. This allows reducing the documentation and at the same time giving nice self-contained examples that should reduce the development time that is otherwise spent in figuring out how the integration and usage of the library works (you can say it's sort of a set of Hello World projects :)). Last but not least you can outline solutions for different use-cases.
I use this approach: http://xilexio.org/?p=125
Namely, place a test
config in the single .pro
file that builds everything. File hierarchy:
myproject.pro
src/
Example1.cpp
Example2.cpp
Example1.h
Example2.h
test/
ExampleTest.cpp
ExampleTest.h
myproject.pro
file:
QT += #needed modules
CONFIG += qt c++11
HEADERS += \
src/Example1.h \
src/Example2.h
SOURCES += \
src/Example1.h \
src/Example2.h
test{
message(Configuring test build...)
TEMPLATE = app
TARGET = myapptests
QT += testlib
HEADERS += \
test/ExampleTest.h
SOURCES += \
test/ExampleTest.cpp
}
else{
TEMPLATE = lib
TARGET = myapp
CONFIG += plugin
TARGET = $$qtLibraryTarget($$TARGET)
}
In my example, I'm building a plugin library, but the method should work for an app as well. In the case of an app, it is likely that SOURCES -= src/main.cpp
is needed under the else
clause, plugin libraries don't have it. If this is not done, the main()
of the app will clash with the main()
of the unit tests.
ExampleTest.cpp
looks like the following:
#include "ExampleTest.h"
void ExampleTest::exampleTest(){
//Do the tests
}
QTEST_MAIN(ExampleTest)
ExampleTest.h
looks like the following:
#include <QtTest/QtTest>
class ExampleTest : public QObject {
Q_OBJECT
private slots:
void exampleTest();
};
To build the project tests, in a separate directory than the regular build, run:
qmake path/to/myproject.pro "CONFIG += test"
I use Qt Creator by CMake instead of qmake to build my Qt project.
Basically I have to folders:
src
tests
Each test is a program in itself testing a class. The app to be tested is compiled as a library.. You compile all your sources in the folder src as a library.
// ClassTest.cpp
#include "ClassTest.h"
#include "Class2Test.h" // Class of the app
#include <QtTest/QtTest>
ClassTest::ClassTest( QObject* parent )
: QObject(parent)
{
}
QTEST_MAIN( ClassTest )
#include "ClassTest.moc"
You just have to link your lib to your test executable.
Example:
in the src folder CMakeLists.txt example
add_library( MyAPP
SHARED
Class2Test.cpp
)
target_link_libraries( MyAPP
${QT_LIBRARIES}
)
in the tests folder CMakeLists.txt example, for each test.
qt4_automoc( ${test_src} )
add_executable( ${test_name} ${test_src} )
target_link_libraries( ${test_name}
MyAPP
${QT_LIBRARIES}
${QT_QTTEST_LIBRARY}
)
It is still in the same project but you can add a flag to let the user compile the test or not. It is clean because the app stays untouched and it allows you to test each class of your app.