1

I am currently testing a Qt application. I have to build a test to check the correct input and output of csv files.

Problem:

The data is being read asynchronously and my test program is ending before the data is loaded and this is the output i get.

QFATAL: Received signal 11
FAIL! : Received a fatal error

Program flow:

There is a class AsyncLoader that loads the data. After the data read is finished, it emits a completed() signal.

So, I modified the test program to include an QEventLoop. The code is shown below

#pragma once

#include <QEventLoop>
#include <QSignalSpy>
#include "asyncloader.h"
#include "alphaevent.h"
#include "mainwindow.h"
#include <QtTest/QtTest>

class Test1: public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void mainWindowTester();
    void cleanupTestCase();
};

void Test1::initTestCase()
{
  qDebug()<<"hello";
}

void Test1::mainWindowTester()
{    
  AlphaEvent *fs1 = new AlphaEvent(this);

  fs1->setOperation(AlphaEvent::FileOpen);
  fs1->setPath(QString("/home/user/PC5.csv"));

  MainWindow *mw1 = new MainWindow();    

  QEventLoop loop;
  loop.connect(mw1, SIGNAL(completed(FileEvent*)), SLOT(quit()));
  mw1->dataSetIORequest(fs1);
  loop.exec();

  int pqr = mw1->_package->dataSet->rowCount();
  int pqr1 = mw1->_package->dataSet->columnCount();

  qDebug() << "pqr== "<< pqr;
  qDebug() << "-----------------------------------------------";
  QVERIFY(pqr==5);

void Test1::cleanupTestCase()
{
}    

QTEST_MAIN(Test1)
#include "test1.moc"

But with this, I get a "subprocess error: FailedToStart"

Is there a way to test an asynchronous unit?

I am using Qt version 5.4.2, QMake version 3.0

akashrajkn
  • 2,295
  • 2
  • 21
  • 47
  • 1
    would you consider using a unit testing framework like gtest ? – gda2004 Feb 19 '16 at 15:57
  • @gda2004, I haven't tried to use google-test with qt-application before. Will give it a shot if this doesn't work out – akashrajkn Feb 19 '16 at 15:59
  • 2
    @askshrajkn I am currently using gtest with a qt framework you simply need to refactor your code so the slot is a minimal call to a function or method. Then you can write a test using gtest. It might help you isolate where the problem is. – gda2004 Feb 19 '16 at 16:02
  • @gda2004 could you point me to a few resources or examples? and is this plugin (https://github.com/OneMoreGres/qtc-gtest) needed? [i am new to unit-testing, please bear with me] – akashrajkn Feb 19 '16 at 16:03
  • @askshrajkn http://www.ibm.com/developerworks/aix/library/au-googletestingframework.html . I simply forward on the parameters to a function so that I can inject them from the gtest – gda2004 Feb 19 '16 at 16:05
  • Manually adding a `QEventLoop` to a unit test in Qt seems rather suspicious, since `QTEST_MAIN()` instantiates a `QApplication` for you. Without seeing the rest of the code it's impossible to know what's wrong but I'd start by removing the unnecessary extra event loop. – MrEricSir Feb 19 '16 at 17:11
  • @MrEricSir I have edited the question with the entire test program – akashrajkn Feb 19 '16 at 17:18

1 Answers1

1

I try to answer your question 'Is there a way to test an asynchronous unit?' rather than giving hints about how to do it in one framework or another.

The point is, that in unit-testing you are typically aiming at tests that produce deterministic results indpendent of whether you are running them on the development system or the target system. That is, you try to eliminate the influence of task switching on your tests. (Certainly, you also want to have the other kind of tests, but then you are in the realm of integration testing, and in the realm of nondeterministic test results).

To separate your code from the scheduler in unit-testing, you will likely use some of the following approaches:

  • Separate the logic from the synchronization. For example, if you have a synchronization point in the middle of a function, you could extract the code before and after the synchronization point in separate functions and test these functions separately.

  • Double the synchronization functions. For example you could create stubs or mocks for the mutex_lock function. Whenever your double is called, you can then make it simulate the changes that a parallel thread might have done in the meantime.

Many good aspects and links can be found here: How should I unit test threaded code?

Community
  • 1
  • 1
Dirk Herrmann
  • 5,550
  • 1
  • 21
  • 47