Getting strange errors using Unit tests
-
wrote on 18 Jun 2020, 19:10 last edited by nickqu
Hey, I am learning QT and I wrote a unit test:
#ifndef TEST_H #define TEST_H #include <QObject> #include <QtTest/QTest> #include "travelagency.h" #include <stdexcept> class Test : public QObject{ Q_OBJECT public: explicit Test(QObject *parent = 0); private slots: void testCompany(); void testAirline(); void testPrice(); }; #endif // TEST_H
#include "test.h" Test::Test(QObject *parent) : QObject(parent){ } void Test::testCompany(){ TravelAgency* t = new TravelAgency(); int companies = t->getDataForTest()[0]; QCOMPARE(companies,5); } void Test::testAirline(){ TravelAgency* t = new TravelAgency(); QCOMPARE(t->getDataForTest()[1], 3); } void Test::testPrice(){ TravelAgency* t = new TravelAgency(); QCOMPARE(t->getDataForTest()[2], 31); }
These are the errors I get:
********* Start testing of Test ********* Config: Using QtTest library 5.14.2, Qt 5.14.2 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 7.3.0) PASS : Test::initTestCase() A crash occurred in C:\Users\x\Documents\xy\debug\xyz.exe. Function time: 23ms Total time: 41ms Exception address: 0x0000000000407f21 Exception code : 0xc0000005 Stack: # 1: ZN5QTest15toPrettyUnicodeEPKti() - 0x000000006edc27a0 # 2: UnhandledExceptionFilter() - 0x00007ffcb892fd00 # 3: memset() - 0x00007ffcbb522f80 # 4: _C_specific_handler() - 0x00007ffcbb50c5c0 # 5: _chkstk() - 0x00007ffcbb5210b0 # 6: RtlRaiseException() - 0x00007ffcbb4e9e70 # 7: KiUserExceptionDispatcher() - 0x00007ffcbb51fe10 # 8: Unable to obtain symbol # 9: Unable to obtain symbol # 10: ZNK11QMetaMethod6invokeEP7QObjectN2Qt14ConnectionTypeE22QGenericReturnArgument16QGenericArgumentS5_S5_S5_S5_S5_S5_S5_S5_S5_() - 0x0000000068aa2eb0 # 11: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc83f0 # 12: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc83f0 # 13: ZN5QTest5qInitEP7QObjectiPPc() - 0x000000006edc83f0 # 14: ZN5QTest4qRunEv() - 0x000000006edcb0e0 # 15: ZN5QTest5qExecEP7QObjectiPPc() - 0x000000006edcb4d0 # 16: Unable to obtain symbol # 17: Unable to obtain symbol # 18: Unable to obtain symbol # 19: ZN9QMimeType18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv() - 0x0000000068b7bcc0 # 20: ZN7QAction8activateENS_11ActionEventE() - 0x0000000001213d50 # 21: ZN5QMenu7setIconERK5QIcon() - 0x00000000013674d0 # 22: ZN5QMenu10leaveEventEP6QEvent() - 0x000000000136e6f0 # 23: ZN5QMenu17mouseReleaseEventEP11QMouseEvent() - 0x000000000136f560 # 24: ZN7QWidget5eventEP6QEvent() - 0x0000000001254ec0 # 25: ZN5QMenu5eventEP6QEvent() - 0x0000000001371710 # 26: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x0000000001217980 # 27: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x000000000121e370 # 28: ZN16QCoreApplication20sendSpontaneousEventEP7QObjectP6QEvent() - 0x0000000068a95690 # 29: ZN19QApplicationPrivate14sendMouseEventEP7QWidgetP11QMouseEventS1_S1_PS1_R8QPointerIS0_Ebb() - 0x000000000121d910 # 30: ZN14QDesktopWidget11qt_metacallEN11QMetaObject4CallEiPPv() - 0x0000000001266e20 # 31: ZN14QDesktopWidget11qt_metacallEN11QMetaObject4CallEiPPv() - 0x0000000001266e20 # 32: ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent() - 0x0000000001217980 # 33: ZN12QApplication6notifyEP7QObjectP6QEvent() - 0x000000000121e370 # 34: ZN16QCoreApplication20sendSpontaneousEventEP7QObjectP6QEvent() - 0x0000000068a95690 # 35: ZN22QGuiApplicationPrivate17processMouseEventEPN29QWindowSystemInterfacePrivate10MouseEventE() - 0x0000000061977640 # 36: ZN22QGuiApplicationPrivate24processWindowSystemEventEPN29QWindowSystemInterfacePrivate17WindowSystemEventE() - 0x0000000061978f00 # 37: ZN22QWindowSystemInterface22sendWindowSystemEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE() - 0x0000000061951400 # 38: ZN21QEventDispatcherWin3213processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE() - 0x0000000068af0800 # 39: qt_plugin_instance() - 0x000000006a8fd210 # 40: ZN10QEventLoop4execE6QFlagsINS_17ProcessEventsFlagEE() - 0x0000000068a93780 # 41: ZN16QCoreApplication4execEv() - 0x0000000068a9d0e0 # 42: Unable to obtain symbol # 43: Unable to obtain symbol # 44: Unable to obtain symbol # 45: BaseThreadInitThunk() - 0x00007ffcba337bc0 # 46: RtlUserThreadStart() - 0x00007ffcbb4ece30
I don't know what I'm doung wrong here I need help.
My OS is Windows 10 and I am using Qt Creator 4.11.2 Based on Qt 5.14.2 (MSVC 2017, 32 bit) if that makes any difference.
-
The vectors don't get filled in the test. They get filled in te while loop in on_actionDatei_einlesen_triggered() function with the fillVectors() function.
The way that I was expecting it was this: I run the programm. The Programm Window opens. I choose a file. The while loop fills the vector(s) with the fillVectors() method.
Until now it works, becausecout << "vector A size: " << a.size() << endl;
right after the while loop, displays the correct vector size.
Now I execute the test
Test test; QTest::qExec(&test);
And the getter function returns the correct vector size in the test.
@nickqu said in Getting strange errors using Unit tests:
The way that I was expecting it was this: I run the programm. The Programm Window opens. I choose a file. The while loop fills the vector(s) with the fillVectors()
This is not how unit tests work.
There should not be any interaction with users.
Why don't you simply call on_actionDatei_einlesen_triggered() in the test before checking the vector size? -
Hi and welcome to devnet,
One thing to exclude a Qt issue, can you successfully run the tests if the body of the methods are empty ?
-
wrote on 18 Jun 2020, 19:21 last edited by
Hey SGaist,
thank you for your help. I erased the body and I don't get any errors. All tests pass.
********* Start testing of Test ********* Config: Using QtTest library 5.14.2, Qt 5.14.2 (x86_64-little_endian-llp64 shared (dynamic) release build; by GCC 7.3.0) PASS : Test::initTestCase() PASS : Test::testCompany() PASS : Test::testAirline() PASS : Test::testPrice() PASS : Test::cleanupTestCase() Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 27ms ********* Finished testing of Test *********
What am I doing wrong?
-
Well, it looks like you have a bug somewhere in the code you are testing.
-
wrote on 19 Jun 2020, 07:25 last edited by nickqu
I have a follow up question. I was able to fix the issue with the strange errors.
I developed a UI in wich a user can choose a .txt file from the system and the data will be displayed in a table widget. It data is also being processed and put in vectors.
void TravelAgency::on_actionDatei_einlesen_triggered(){ QFile file(QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Text (*.txt)"))); if (!file.exists()) return; file.open(QIODevice::ReadOnly | QIODevice::Text); if (!file.isOpen()) cerr << "error..."; QTextStream stream(&file); QString line = stream.readLine(); while (!line.isNull()) { string sLine = line.toStdString(); fillVectors(sLine.at(0), sLine.substr(2)); line = stream.readLine(); } cout << "vector A size: " << a.size() << endl; //return a non zero value but the getter function returns 0 in the unit test. Test test; QTest::qExec(&test); }
And lets say I have a getter Method wich simply return the size of the vector which was filled and I have the following test:
#include "test.h" Test::Test(QObject *parent) : QObject(parent){ } void Test::testCompany(){ TravelAgency* t = new TravelAgency(); int sizeA= t->getSizeOfVectorA(); QCOMPARE(sizeA,5); }
The test fails because the getter function returns the value 0, but I am expecting a non zero value. Am I doing something wrong?
-
I have a follow up question. I was able to fix the issue with the strange errors.
I developed a UI in wich a user can choose a .txt file from the system and the data will be displayed in a table widget. It data is also being processed and put in vectors.
void TravelAgency::on_actionDatei_einlesen_triggered(){ QFile file(QFileDialog::getOpenFileName(this, tr("Open File"), "/home", tr("Text (*.txt)"))); if (!file.exists()) return; file.open(QIODevice::ReadOnly | QIODevice::Text); if (!file.isOpen()) cerr << "error..."; QTextStream stream(&file); QString line = stream.readLine(); while (!line.isNull()) { string sLine = line.toStdString(); fillVectors(sLine.at(0), sLine.substr(2)); line = stream.readLine(); } cout << "vector A size: " << a.size() << endl; //return a non zero value but the getter function returns 0 in the unit test. Test test; QTest::qExec(&test); }
And lets say I have a getter Method wich simply return the size of the vector which was filled and I have the following test:
#include "test.h" Test::Test(QObject *parent) : QObject(parent){ } void Test::testCompany(){ TravelAgency* t = new TravelAgency(); int sizeA= t->getSizeOfVectorA(); QCOMPARE(sizeA,5); }
The test fails because the getter function returns the value 0, but I am expecting a non zero value. Am I doing something wrong?
@nickqu said in Getting strange errors using Unit tests:
but I am expecting a non zero value
Why?
You did not fill the vector, right? -
wrote on 19 Jun 2020, 07:36 last edited by
The vector is filled correctly. It all works fine. While I was doing some debugging:
cout << "vector A size: " << a.size() << endl;
displayed the correct size value of the vector. Before I am doing
Test test; QTest::qExec(&test);
But the getter simply returns 0 in the test. I don't know why...
-
The vector is filled correctly. It all works fine. While I was doing some debugging:
cout << "vector A size: " << a.size() << endl;
displayed the correct size value of the vector. Before I am doing
Test test; QTest::qExec(&test);
But the getter simply returns 0 in the test. I don't know why...
@nickqu Where do you fill the vector? You do not fill it in the constructor, right? And on_actionDatei_einlesen_triggered() is not called in your test.
Can you show your getter? -
wrote on 19 Jun 2020, 07:54 last edited by
No, I fill the vector in the fillVectors() function.
Is it necessary that I call on_actionDatei_einlesen_triggered() in my test? Because I am running the program and choosing a file from the .txt system. So I trigger the function which takes the .txt file processes it and fills the vector(s). And then I am exec. the test?
The getter function is simly:
``
int TravelAgency::getSizeOfVectorA(){ return a.size(); } -
No, I fill the vector in the fillVectors() function.
Is it necessary that I call on_actionDatei_einlesen_triggered() in my test? Because I am running the program and choosing a file from the .txt system. So I trigger the function which takes the .txt file processes it and fills the vector(s). And then I am exec. the test?
The getter function is simly:
``
int TravelAgency::getSizeOfVectorA(){ return a.size(); }@nickqu said in Getting strange errors using Unit tests:
Is it necessary that I call on_actionDatei_einlesen_triggered()
It is necessary that the vector gets filled somehow and in the test code you posted I don't see anything like that.
Where do you fill the vector in this code:void Test::testCompany(){ TravelAgency* t = new TravelAgency(); int sizeA= t->getSizeOfVectorA(); QCOMPARE(sizeA,5); }
?
-
wrote on 19 Jun 2020, 08:10 last edited by
The vectors don't get filled in the test. They get filled in te while loop in on_actionDatei_einlesen_triggered() function with the fillVectors() function.
The way that I was expecting it was this: I run the programm. The Programm Window opens. I choose a file. The while loop fills the vector(s) with the fillVectors() method.
Until now it works, becausecout << "vector A size: " << a.size() << endl;
right after the while loop, displays the correct vector size.
Now I execute the test
Test test; QTest::qExec(&test);
And the getter function returns the correct vector size in the test.
-
The vectors don't get filled in the test. They get filled in te while loop in on_actionDatei_einlesen_triggered() function with the fillVectors() function.
The way that I was expecting it was this: I run the programm. The Programm Window opens. I choose a file. The while loop fills the vector(s) with the fillVectors() method.
Until now it works, becausecout << "vector A size: " << a.size() << endl;
right after the while loop, displays the correct vector size.
Now I execute the test
Test test; QTest::qExec(&test);
And the getter function returns the correct vector size in the test.
@nickqu said in Getting strange errors using Unit tests:
The way that I was expecting it was this: I run the programm. The Programm Window opens. I choose a file. The while loop fills the vector(s) with the fillVectors()
This is not how unit tests work.
There should not be any interaction with users.
Why don't you simply call on_actionDatei_einlesen_triggered() in the test before checking the vector size? -
wrote on 19 Jun 2020, 08:51 last edited by nickqu
@jsulm thanks, it works now. But how can I make it, so that in the test on_actionDatei_einlesen_triggered() ist executed, when the (menu) button was clicked? Right now I get asked to choose a file as soon as the programm starts and not when the button is clicked...
-
@jsulm thanks, it works now. But how can I make it, so that in the test on_actionDatei_einlesen_triggered() ist executed, when the (menu) button was clicked? Right now I get asked to choose a file as soon as the programm starts and not when the button is clicked...
@nickqu Take a look at https://doc.qt.io/qt-5/qtest.html
There are several mousePress overloads. -
@jsulm can you make an example? I don't understand how the mousePress overloads are goingt to help me with my case.
@nickqu Take a look at https://doc.qt.io/qt-5/qttestlib-tutorial3-example.html
1/16