PDA

View Full Version : QtTest: forced to #include .cpp file



Urthas
1st August 2015, 00:48
Hello,

I just posted a different question about the same testing code here (http://www.qtcentre.org/threads/63279-Running-select-unit-test%28s%29-only?p=280355#post280355).

My test suite includes a class called TestOutgoingCall, which tests a class called -- surprise surprise -- OutgoingCall. That class lives one directory up. As a convenience, therefore, I added .. to the INCLUDEPATH of my test .pro file:


QT += core testlib
TEMPLATE = app
TARGET = test
INCLUDEPATH += . ..

# Input
SOURCES += \
main.cpp \
testoutgoingcall.cpp \
testscopelock.cpp

HEADERS += \
testoutgoingcall.h \
testscopelock.h \
testcase.h

Here is testoutgoingcall.h:


#ifndef TESTOUTGOINGCALL_H
#define TESTOUTGOINGCALL_H

#include "testcase.h"

class OutgoingCall;

class TestOutgoingCall : public TestCase
{
Q_OBJECT
private slots:
void initTestCase();
void cleanupTestCase();

private:
OutgoingCall *call;
};

#endif // TESTOUTGOINGCALL_H

and here is the .cpp file:


#include "testoutgoingcall.h"

#include "OutgoingCall.h"
#include "OutgoingCall.cpp" // FIXME WHY DO WE NEED THIS TO COMPILE?! 07.31.15

void TestOutgoingCall::initTestCase() {
call = new OutgoingCall("", "");
}

void TestOutgoingCall::cleanupTestCase() {
delete call;
}

As you can see, the implementation is as yet trivial, which is fine. The problem is that if I remove #include "OutgoingCall.cpp" I get the following compiler errors:


Undefined symbols for architecture x86_64:
"OutgoingCall::OutgoingCall(QString, QString)", referenced from:
TestOutgoingCall::initTestCase() in testoutgoingcall.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test.app/Contents/MacOS/test] Error 1
15:43:14: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project test (kit: Desktop Qt 5.5.0 clang 64bit)
When executing step "Make"

The constructor for Outgoing call takes two QStrings. Everything works when I un-comment that include.

What is going on here? I'm fairly certain that including a .cpp file after the .h file is the Wrong Way To Do It. :)

Any insight is appreciated.

Thank you!

ChrisW67
1st August 2015, 03:00
The test program needs to be complete, that is, it must have an implementation of OutgoingCall and not just a declaration. The linker cannot find the implementation, i.e. Undefined symbols, and fails to put together a complete program. Your PRO file does not pull that implementation in either as a SOURCES or linked as part of a library. Your #include kludge drags the source of the implementation directly into your test source code, making the implementation available.

The cleaner way would be adding to SOURCES. If the OutgoingCall class is a QObject then you should also add the header to the HEADERS variable so that moc gets to see it.



QT += core testlib
TEMPLATE = app
TARGET = test
INCLUDEPATH += . ..

# Input
SOURCES += \
main.cpp \
testoutgoingcall.cpp \
testscopelock.cpp \
..\OutgoingCall.cpp

HEADERS += \
testoutgoingcall.h \
testscopelock.h \
testcase.h \
..\OutgoingCall.h


The INCLUDEPATH is only used to find included files that are not literally where the #include says. The INCLUDEPATH ".." entry is necessary if you wish to use:


#include "OutgoingCall.h"
// instead of
#include "../OutgoingCall.h"

in your test code.