在使用 QTestLib 时禁止 qDebug

Suppress qDebug when using QTestLib

本文关键字:禁止 qDebug QTestLib      更新时间:2023-10-16

我正在向Qt中的项目添加单元测试,并希望使用QTestLib。我已经设置了测试,它们运行良好。

问题是在项目中,我们已经覆盖了 qDebug() 以输出到我们自己的日志文件中。这在运行应用程序时效果很好,问题是当我测试类时,它有时会开始日志记录,然后将其发送到输出窗口。结果是一场完全的灾难,几乎无法读取,因为我们的日志与 QTest 输出混合在一起。

我想知道是否有办法抑制 qDebug() 输出,或者至少将其移动到其他地方。我尝试添加#define QT_NO_DEBUG_OUTPUT并使用qInstallMsgHandler(messageOutput);来重定向或阻止输出,但都没有任何效果。

@Kuba给出的解决方案在某些情况下有效,但当与 main 方法中的QTest::qExec(&test,argc,argv)结合使用以运行许多测试时则不起作用。在这种情况下,禁用 qDebug() 输出(我发现的)的唯一方法是让每个测试类在其void initTestCase()槽中注册一个新的消息处理程序。

例如

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);     
}

将显示调试输出tst_Class1、类 1、tst_Class2 和类 2。若要防止这种情况,必须显式禁用每个测试类中的输出

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);
}

如果您希望看到类子集的调试输出,请删除qInstallMsgHandler()行,它将通过。

  1. QT_NO_DEBUG_OUTPUT定义必须进入项目文件或生成文件,并且必须存在于编译的每个文件中。然后,您必须重新编译您的应用程序(当然不是Qt本身)。此宏在编译器命令行上的存在保证了任何代码首次包含QDebug标头时,qDebug将被重新定义为无操作。这就是此宏的作用:当包含<QtCore/qdebug.h>标头时,它禁用qDebug是否存在 - 无论是直接由您还是由其他标头间接。

  2. 使用qInstallMsgHandler当然可以抑制调试输出。

下面是一个自包含的示例。

#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";
}