我的Qt应用程序使用Q_ASSERT_X,它调用qFatal(),默认情况下会中止应用程序。这对应用程序来说很好,但是我想在单元测试应用程序时抑制这种行为。 (我正在使用Google Test Framework。)我在一个单独的项目中进行单元测试,静态链接到我正在测试的类。 qFatal()的documentation读取:
使用。调用消息处理程序 致命的消息如果没有消息 处理程序已安装, 消息打印到stderr。下 Windows,将消息发送给 调试器。
如果您使用的是默认消息 处理程序此函数将中止 Unix系统创建核心转储。上 Windows,用于调试版本,这个 函数将报告_CRT_ERROR 使您能够将调试器连接到 申请。
...
要在运行时压缩输出, 安装自己的消息处理程序 qInstallMsgHandler()。
所以这是我的main.cpp文件:
#include <gtest/gtest.h>
#include <QApplication>
void testMessageOutput(QtMsgType type, const char *msg) {
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s\n", msg);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s\n", msg);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s\n", msg);
break;
case QtFatalMsg:
fprintf(stderr, "My Fatal: %s\n", msg);
break;
}
}
int main(int argc, char **argv)
{
qInstallMsgHandler(testMessageOutput);
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
但是我的申请仍然停留在断言。我可以告诉我正在调用我的自定义处理程序,因为运行我的测试时的输出是:
我的致命:ASSERT失败了 MyClass :: doSomething:“doSomething()”, file myclass.cpp,第21行程序 意外地完成了。
即使断言失败,我还能做什么让我的测试继续运行?
答案 0 :(得分:4)
Q_ASSERT_X无法编译。
因此,对于单元测试,请执行发布版本,它不会调用qFatal。
答案 1 :(得分:2)
-DqFatal = qCritical:)
答案 2 :(得分:1)
至少对于Qt-4.6.2,你无能为力。
src/corelib/global/qglobal.cpp
定义void qt_message_output(QtMsgType msgType, const char *buf)
,它首先检查是否已安装处理程序。如果是这样,它会调用它,否则它使用默认处理程序。紧接着,它几乎总是中止(Unix / MingWn)或调用exit(其他)。
我无法在线找到当前源代码的浏览器,但the Qt-4.2.2 source code is mostly identical并且应该让您大致了解发生了什么。
答案 3 :(得分:0)
在某些情况下,您可能无法抑制qFatal并继续静默,已测试的组件可能处于这样的状态,即无论如何都会在几行之后发生崩溃。避免这种情况的一种方法是在测试代码的某处存根qFatal;)
void qFatal(const char *msg, ...)
{
QT_THROW(std::some_exception);
}
然后你可以拥有一些自己的断言宏:
#define CUSTOM_QEXPECT_FAIL( method ) { bool failed = false;\
try { \
method ; \
}\
catch(...) { \
failed = true; \
} \
QVERIFY(failed); }
并在您的代码中使用它,如:
CUSTOM_QEXPECT_FAIL( testedObj->panicAtTheDisco() );
并不是说这是一种不错的方法,只是试图证明可以为这个问题做些什么。
另外,我没有仔细阅读,你是静态链接测试类。在这种情况下,只有在您将其构建到测试可执行文件中时,存根才可能起作用。