Как структурировать проект при модульном тестировании приложения Qt с помощью QTestLib

У меня есть проект Qt, и я использую Qt Creator. Я хочу провести модульное тестирование всего своего кода.
Однако я новичок в среде QTestLib, но все рекомендовали ее для тестирования исходного кода на основе Qt. Теперь я немного запутался, как структурировать тестовый проект с проектом приложения.

  1. Могу ли я поместить весь исходный и тестовый код в один проект? Если да, то как я мог управлять ими? Я не нашел ни одного варианта, который позволил бы мне запустить приложение или запустить тест в одном проекте.
  2. Если я помещу исходный код приложения и код тестирования в отдельные проекты, проект тестирования будет ссылаться на проект приложения, что не совсем удобно.
  3. Для партий классов, которые необходимо протестировать, как мне управлять тестируемым кодом?

Как вы, ребята, управляете тестированием кода в такой ситуации? Спасибо.


person fifth    schedule 28.08.2012    source источник
comment
пятый.. вы можете принять больше ответов??   -  person UmNyobe    schedule 17.12.2012
comment
Конечно. @UmNyobe, я наконец развернул исходный и тестовый код в отдельных проектах. Тестовый проект ссылался на те же источники по файлу pri с относительным путем.   -  person fifth    schedule 18.12.2012
comment
если вы дадите четкое описание того, что вы сделали, вы получите мою награду: D   -  person UmNyobe    schedule 18.12.2012
comment
@UmNyobe, извините за поздний ответ, просто проверьте мой пост ниже   -  person fifth    schedule 25.12.2012


Ответы (4)


Источник первой структуры, как показано ниже:

MyApp
MyAppUnitTest

В проекте MyApp используйте MyAppSrc.pri для поиска исходных файлов:

SOURCES += \
    ../../../framework/src/myapp.cpp \
    ../../../framework/src/mycontrol.cpp

HEADERS += \
    ../../../framework/inc/myapp.h \
    ../../../framework/inc/mycontrol.h

INCLUDEPATH += ../../../framework/extlibs

Включите это .pri в MyApp.pro, например:

include(MyAppSrc.pri)

Затем структурируйте проект тестирования точно так же, как основной проект, с одним дополнительным включением в MyAppUnitTest.pro:

include(MyAppUnitTestSrc.pri)
include(../MyApp/MyAppSrc.pri)
person fifth    schedule 25.12.2012
comment
При таком подходе исходный код компилируется дважды (один раз для MyApp и один раз для MyAppUnitTest)? - person Terrabits; 12.07.2018

Я использую такой подход: http://xilexio.org/?p=125

А именно, поместите конфиг test в единственный файл .pro, который все строит. Файловая иерархия:

myproject.pro
src/
    Example1.cpp
    Example2.cpp
    Example1.h
    Example2.h
test/
    ExampleTest.cpp
    ExampleTest.h

myproject.pro файл:

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)
}

В моем примере я создаю библиотеку плагинов, но этот метод должен работать и для приложения. В случае с приложением, скорее всего, в пункте else требуется SOURCES -= src/main.cpp, в библиотеках плагинов его нет. Если этого не сделать, main() приложения будет конфликтовать с main() модульных тестов.

ExampleTest.cpp выглядит следующим образом:

#include "ExampleTest.h"

void ExampleTest::exampleTest(){
    //Do the tests
}

QTEST_MAIN(ExampleTest)

ExampleTest.h выглядит следующим образом:

#include <QtTest/QtTest>

class ExampleTest : public QObject {
Q_OBJECT

private slots:
    void exampleTest();
};

Чтобы собрать тесты проекта, в отдельном каталоге, чем обычная сборка, запустите:

qmake path/to/myproject.pro "CONFIG += test"
person Ayberk Özgür    schedule 29.04.2016
comment
Итак, как мне заставить qmake попасть в этот test {Configuring test build...} ... случай? - person George; 30.04.2021

Мне нравятся другие ответы, но я также хотел бы оставить отзыв о том, как мы это делаем в компании, в которой я сейчас работаю:

  1. Создайте проект subdirs (это будет проект верхнего уровня, который будет управлять ВСЕМИ, включая ваш библиотечный проект или все, что вы хотите протестировать)

    +-----MyProject (top-level subdirs)
    
  2. Добавьте свои библиотечные проекты в качестве подпроекта

    +-----MyProject (top-level subdirs)
              |
              +-----Library (library project, UI project etc.)
    
  3. Добавьте еще subdirs проектов (для тестов)

    +-----MyProject (top-level subdirs)
              |
              +-----Library (library project, UI project etc.)
              |
              +-----Tests (subdirs for tests)
    
  4. Создайте проект QUnitTest и добавьте его в проект subdirs тестирования.

    +-----MyProject (subdirs)
              |
              +-----Library (library project, UI project etc.)
              |
              +-----Tests (subdirs for tests)
                      |
                      +----- TestA (QUnitTest project for testing feature A)
    
  5. Добавьте столько тестов, сколько считаете нужным

             ...
              |
              +-----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)
    

Если вам нужно сгруппировать тесты в группы, вы также можете использовать subdirs для этого. subdirs также обеспечивает создание настоящих каталогов в вашей файловой системе. Если вы хотите избежать слишком много subdirsing, вы можете сгруппировать тесты в папках, которые вы создали самостоятельно в своей файловой системе внутри папки проекта Tests.

Кроме того, я бы также рекомендовал добавить subdirs для проектов-шаблонов.

+-----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)

Это, конечно, основано на функциональности вашей библиотеки. Под шаблонными проектами я подразумеваю пользовательские виджеты и т. д., которые ссылаются на вашу библиотеку и раскрывают выборочно (или все) ее функциональные возможности так, как они должны отображаться для пользователя. Например, если у вас есть библиотека, которая управляет различными устройствами камеры, вы можете создать проект шаблона для каждого устройства камеры, что позволит пользователям вашей библиотеки просто скопировать и вставить конкретный проект шаблона и расширить его или, по крайней мере, посмотреть, как интеграция ваша библиотека должна произойти в целом. Это позволяет сократить документацию и в то же время дать хорошие самостоятельные примеры, которые должны сократить время разработки, которое в противном случае тратится на выяснение того, как работает интеграция и использование библиотеки (можно сказать, что это своего рода набор Hello World проекты :)). И последнее, но не менее важное: вы можете наметить решения для различных вариантов использования.

person rbaleksandar    schedule 02.11.2016

Я использую Qt Creator от CMake вместо qmake для сборки своего проекта Qt.

В основном у меня есть папки:

src
tests

Каждый тест сам по себе является программой, тестирующей класс. Тестируемое приложение скомпилировано в виде библиотеки. Вы компилируете все свои исходники в папку src как библиотеку.

// 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"

Вам просто нужно связать свою библиотеку с исполняемым файлом теста.

Пример:

в папке src пример CMakeLists.txt

add_library( MyAPP
    SHARED
    Class2Test.cpp
)
target_link_libraries( MyAPP
    ${QT_LIBRARIES}
)

в папке тестов CMakeLists.txt пример для каждого теста.

qt4_automoc( ${test_src} )
add_executable( ${test_name} ${test_src} )
target_link_libraries( ${test_name}
    MyAPP
    ${QT_LIBRARIES}
    ${QT_QTTEST_LIBRARY}
)

Он все еще находится в том же проекте, но вы можете добавить флаг, позволяющий пользователю компилировать тест или нет. Это чисто, потому что приложение остается нетронутым и позволяет вам тестировать каждый класс вашего приложения.

person Kirell    schedule 21.12.2012
comment
немного трудно читать из-за именования. Что такое тестовый класс и какой класс тестировать? - person relascope; 17.05.2015