How to structure project while unit-testing Qt app by QTestLib

后端 未结 4 1834
闹比i
闹比i 2020-12-23 16:28

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

相关标签:
4条回答
  • 2020-12-23 17:10

    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)
    
    0 讨论(0)
  • 2020-12-23 17:14

    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:

    1. 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)
      
    2. Add your library projects as a sub-project

      +-----MyProject (top-level subdirs)
                |
                +-----Library (library project, UI project etc.)
      
    3. Add another subdirs projects (for the tests)

      +-----MyProject (top-level subdirs)
                |
                +-----Library (library project, UI project etc.)
                |
                +-----Tests (subdirs for tests)
      
    4. 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)
      
    5. 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 subdirsing 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.

    0 讨论(0)
  • 2020-12-23 17:28

    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"
    
    0 讨论(0)
  • 2020-12-23 17:35

    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.

    0 讨论(0)
提交回复
热议问题