5

I am adding unit tests to project in Qt and am looking to use QTestLib. I have set up the tests and they are running fine.

The issue is that in the project we have overridden qDebug() to output to our own log file. This works great when running the app, the problem is that when I am testing the classes, it will sometimes start logging, which is then sent to the output window. The result is a complete disaster that is next to impossible to read as our logs get mixed in with the QTest output.

I am wondering if there is a way to suppress the qDebug() output, or at least move it somewhere else. I have tried adding #define QT_NO_DEBUG_OUTPUT and also using qInstallMsgHandler(messageOutput); to redirect or prevent the output, but neither had any effect.

Adam
  • 982
  • 7
  • 16

2 Answers2

9

The solution given by @Kuba works in some cases, but not when used in conjunction with QTest::qExec(&test,argc,argv) in the main method to run a number of tests. In that case the only way to disable the qDebug() output (that I found) is for each of the test classes in their void initTestCase() slot to register a new message handler.

For example

void noMessageOutput(QtMsgType, const char *)
{}

int main(int argc,char* argv[])
{
  qInstallMsgHandler(noMessageOutput);
  tst_Class1 t1;
  tst_Class2 t2;
  QTest::qExec(&t1,argc,argv);
  QTest::qExec(&t2,argc,argv);     
}

Will show the debug output tst_Class1, Class1, tst_Class2, and Class2. To prevent this you must explicitly disable the output in each of the test classes

class tst_Class1
{
   //class stuff
   private slots:
      void initTestCase();
      //test cases
};

void tst_Class1::initTestCase()
{
      qInstallMsgHandler(noMessageOutput);
}

class tst_Class2
{
   //class stuff
   private slots:
      void initTestCase();
      //test cases
};

void tst_Class2::initTestCase()
{
      qInstallMsgHandler(noMessageOutput);
}

If you wish to see the debug output from a subset of the classes the remove the qInstallMsgHandler() line and it will come through.

Adam
  • 982
  • 7
  • 16
6
  1. The QT_NO_DEBUG_OUTPUT define must go into your project files or makefiles and must be present for every file you compile. You must then recompile your application (not Qt itself of course). This macro's presence on compiler's command line guarantees that the first time QDebug header is included by any code, the qDebug will be redefined to a no-op. That's what this macro does: it disables qDebug if it is present when the <QtCore/qdebug.h> header gets included -- whether directly by you or indirectly by other headers.

  2. Using qInstallMsgHandler certainly works at suppressing debug output.

Below is a self-contained example.

#if 0
// Enabling this section disables all debug output from non-Qt code.
#define QT_NO_DEBUG_OUTPUT
#endif
#include <QtCore/QDebug>

void noMessageOutput(QtMsgType, const char *)
{}

int main(int argc, char *argv[])
{
    qDebug() << "I'm shown";
    qInstallMsgHandler(noMessageOutput);
    qDebug() << "I'm hidden";
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • 2
    Thanks. I found the only way to register the noMessageOutput was to do it in the initTestCase() slot of each of the test cases, but I have it working now – Adam Jun 18 '12 at 13:42