[SOLVED] QTest an subprojects: How to link against application with "TEMPLATE = app" configuration?
-
Hi :)
I'm currently trying to make Unit-Testing (QTest) work in my project. I took "this ":https://gitorious.org/qwebservice/qwebservice/source project as an reference on how I could struture the whole thing.
However, I've been trying to find a solution for a "undefined reference"-error for hours now. Anyway, let me first describe what my project looks like now:
This is my current filestructure (please note that my project is a lot bigger, but these are the essential parts):
@
MyAppbuildInfo.pri (A) libraryIncludes.pri (B) MyApp.pro (C) |
+---build+---src ---tests +---MyApp
| | MyApp.pro (D)
| | deployment.pri
| | inputvectors.h (E)
| | inputvectors.cpp (F)
| | main.cpp
| |
---tests
| tests.pro (G)
\ testinputvectors.cpp (H)
@File A (buildInfo.pri):
@
ROOT_DIRECTORY = $$PWD
BUILD_DIRECTORY = $${ROOT_DIRECTORY}/build
TESTS_DIRECTORY = $${BUILD_DIRECTORY}/tests
@File B (libraryIncludes.pri):
@
INCLUDEPATH += $$PWD/MyApp
DEPENDPATH += $$PWD/MyApp
@File C (MyApp.pro):
@
include(buildInfo.pri)This variable contains the name of the template to use when generating the project.
"subdirs"-option: Creates a Makefile for building targets in subdirectories.
The subdirectories are specified using the SUBDIRS variable. For more information see:
http:#qt-project.org/doc/qt-5/qmake-variable-reference.html#template
TEMPLATE = subdirs
specify directory for target file
DESTDIR = $${BUILD_DIRECTORY}
where to place intermediate object files
OBJECTS_DIR = $${BUILD_DIRECTORY}
where to place intermediate moc files
MOC_DIR = $${BUILD_DIRECTORY}
SUBDIRS +=
MyApp
tests
@File D (MyApp.pro):
@
include(../buildInfo.pri)TEMPLATE = app
QT += qml
quick
gui
widgets
corespecify directory for target file
DESTDIR = $${BUILD_DIRECTORY}
where to place intermediate object files
OBJECTS_DIR = $${BUILD_DIRECTORY}
where to place intermediate moc files
MOC_DIR = $${BUILD_DIRECTORY}
SOURCES += main.cpp
inputvectors.cpp \RESOURCES += qml.qrc
Default rules for deployment.
include(deployment.pri)
HEADERS +=
inputvectors.h
@File E (inputvectors.h):
@
#ifndef INPUTVECTORS_H
#define INPUTVECTORS_H#include <QList>
#include <QString>class InputVectors
{public:
InputVectors();
InputVectors(QList<QString> columnHeadings,
QList<QList<unsigned int> > table);QList<QString> getHeadings(); QList<QList<unsigned int> > getValues();
private:
QList<QString> columnHeadings;
QList<QList<unsigned int> > table;
};#endif // INPUTVECTORS_H
@File F (inputvectors.cpp):
@
#include "inputvectors.h"InputVectors::InputVectors(QList<QString> columnHeadings,
QList<QList<unsigned int> > table)
{
this->table = table;
this->columnHeadings = columnHeadings;
}QList<QList<unsigned int> > InputVectors::getValues()
{
return this->table;
}QList<QString> InputVectors::getHeadings()
{
return this->columnHeadings;
}
@File G (tests.pro):
@
include(../buildInfo.pri)QT += testlib
coreCONFIG += testcase
include(../libraryIncludes.pri)
DESTDIR = $${TESTS_DIRECTORY}
OBJECTS_DIR = $${TESTS_DIRECTORY}
MOC_DIR = $${TESTS_DIRECTORY}SOURCES +=
testinputvectors.cppFile H (testinputvectors.cpp):,
#include <QtTest/QtTest>#include "inputvectors.h"
class TestInputVectors: public QObject
{
Q_OBJECTprivate slots:
void openFile();
};void TestInputVectors::openFile() {
QList<QString> columnHeadings;
columnHeadings.append("test");
QList<unsigned int> tmp;
tmp.append(2);
QList<QList<unsigned int> > table;
table.append(tmp);
InputVectors test = InputVectors(columnHeadings, table);
}QTEST_MAIN(TestInputVectors)
#include "testinputvectors.moc"
@When I change the "TEMPLATE = app" to "TEMPLATE = lib" in the MyApp.pro (D) file and link it inside the libraryIncludes.pri, it all works as expected. However, when I write the "TEMPLATE = app", I get an error message:
bq. testinputvectors.cpp:20: undefined reference to `InputVectors::InputVectors(QList<QString>, QList<QList<unsigned int> >)'
collect2.exe: error: ld returned 1 exit statusBTW: QtCreate does not mark the #include "inputvectors.h" with a wavy underline as it would normally do if it cannot find a file.
How can I access the functions to be tested from the testing-project?
Thanks in advance,
mozzbozzTL;DR: I have two subprojects (main and tests) on the same layer where I want to test the main "MyApp"-project with the tests placed inside the "tests"-project. However, MyApp is not "TEMPLATE = lib" but "TEMPLATE = app" and I cannot figure out how to correctly access the functions of MyApp from tests.
-
Hi and welcome to devnet,
You can't link against an application.
You have two options there:
Put the core code and tests in a library and use it to build your application
Build the sources you want to test against within test project.
Hope it helps
-
Hmm, that's not the answer I wanted to hear... at least I know now, why I could not get this working.
I think I will place the tests folder inside the main project then, without having a common parent project... Because there is no way to put _everything _ inside a seperate lib.
Thanks!
-
Then use the second technique, build the class for your test along the test
-
Ok, I'm still struggling with this problem. I now have the following:
@
MyApp
|---MyApp.pro
|---myclass.h
|---myclass.cpp
|---main.cpp
|---tests
---testmyclass.cpp
@Inside the testmyclass.cpp-file I have the obligatory
@
QTEST_MAIN(TestFileHandler)
@--> of course I keep getting the
bq. multiple definition of `qMain(int, char**)'
error... I have to admit that I'm a bit puzzled now: How could I organize the testing now? :/
mozzbozz
(unsolved the topic again)
-
Keep the tests outside the app folder
e.g.
MyProject
--- MyApp
--- MyLib(s)
--- MyTests -
Ok, just found "this":http://stackoverflow.com/questions/9780602/using-qt-unit-tests-in-a-project-conflicting-main-functions which says about the same. If I can make this work, I'm gonna resolve this topic again.
Thanks for your help!
-
Thank you SGaist!
Well, I've finally managed to get it up working. The magic was setting the "VPATH variable":http://qt-project.org/doc/qt-5/qmake-variable-reference.html#vpath in qMake.
Just for reference, this is what I have now (in case someone else has the same problems):
@
MyProject--MyApp ---MyApp.pro ---myclass.h ---myclass.cpp ---main.cpp --tests ---tests.pro ---testmyclass.cpp \---main.cpp
@
My tests.pro:
@
include(../buildInfo.pri)QT += core
testlibspecify directory for target file
DESTDIR = $${BUILD_DIRECTORY}_tests
where to place intermediate object files
OBJECTS_DIR = $${BUILD_DIRECTORY}_tests
where to place intermediate moc files
MOC_DIR = $${BUILD_DIRECTORY}_tests
make compiler aware of the application-to-be-tested-directory
(needed for the #include-statements in the sourcecode)
INCLUDEPATH += $${APP_DIRECTORY}
make qmake aware of the application-to-be-tested-directory (so it
will find the files specified in SOURCES and HEADERS)
VPATH += $${PWD}
$${APP_DIRECTORY}SOURCES += main.cpp
myclass.cpp
testmyclass.cppHEADERS +=
myclass.h
testmyclass.h
@My buildInfo.pri:
@
ROOT_DIRECTORY = $$PWD
APP_DIRECTORY = $$PWD/MyApp
BUILD_DIRECTORY = $${ROOT_DIRECTORY}/build
@My testmyclass.h:
@
#ifndef TESTFILEHANDLER_H
#define TESTFILEHANDLER_H#include <QObject>
class TestMyClass: public QObject
{
Q_OBJECTprivate slots:
void myTest();
};#endif // TESTFILEHANDLER_H
@My testmyclass.cpp:
@
#include <QtTest/QtTest>
#include "myclass.h"void TestFileHandler::myTest() {
MyClass c;
QCOMPARE(c.printHello(), "Hello");
}
@