Unit testing 如何防止qFatal()中止应用程序?
我的Qt应用程序使用Q_ASSERT_X,它调用qFatal(),默认情况下,qFatal()会中止应用程序。这对于应用程序来说非常好,但是我想在对应用程序进行单元测试时抑制这种行为。(我正在使用。)我在一个单独的项目中进行了单元测试,静态链接到我正在测试的类。for qFatal()的命令如下: 使用 致命消息消息消息。如果没有消息 已安装处理程序,则 消息被打印到stderr。在下面 Windows,则消息将发送到 调试器 如果您使用的是默认消息 处理程序此函数将在上中止 Unix系统创建核心转储。在…上 Windows,对于调试版本,此 函数将报告一个_CRT_错误 使您能够将调试器连接到 应用程序 要在运行时抑制输出, 使用安装您自己的消息处理程序 qInstallMsgHandler() 这是我的主.cpp文件:Unit testing 如何防止qFatal()中止应用程序?,unit-testing,qt,googletest,Unit Testing,Qt,Googletest,我的Qt应用程序使用Q_ASSERT_X,它调用qFatal(),默认情况下,qFatal()会中止应用程序。这对于应用程序来说非常好,但是我想在对应用程序进行单元测试时抑制这种行为。(我正在使用。)我在一个单独的项目中进行了单元测试,静态链接到我正在测试的类。for qFatal()的命令如下: 使用 致命消息消息消息。如果没有消息 已安装处理程序,则 消息被打印到stderr。在下面 Windows,则消息将发送到 调试器 如果您使用的是默认消息 处理程序此函数将在上中止 Unix系统创建核
#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();
}
#包括
#包括
void testMessageOutput(QtMsgType类型,const char*msg){
开关(类型){
案例QtDebugMsg:
fprintf(stderr,“调试:%s\n”,msg);
打破
案例QtWarningMsg:
fprintf(stderr,“警告:%s\n”,msg);
打破
案例QTSG:
fprintf(标准,“关键:%s\n”,消息);
打破
案例QTALMSG:
fprintf(stderr,“我的致命错误:%s\n”,msg);
打破
}
}
int main(int argc,字符**argv)
{
qInstallMsgHandler(testMessageOutput);
测试:InitGoogleTest(&argc,argv);
返回运行所有测试();
}
但我的应用程序仍在断言处停止。我可以看出正在调用我的自定义处理程序,因为运行测试时的输出是:
我的致命弱点:断言失败
MyClass::doSomething:“doSomething()”,
文件myclass.cpp,程序第21行
意外地完成了
我该怎么做才能使我的测试即使在断言失败时也能继续运行?至少对于Qt-4.6.2,您无能为力
src/corelib/global/qglobal.cpp
定义了void qt_message_输出(QtMsgType msgType,const char*buf)
,首先检查是否安装了处理程序。如果是,则调用它,否则使用默认处理程序。紧接着,它几乎总是中止(Unix/MingWn)或调用exit(其他)
我在网上找不到当前源代码的浏览器,但应该可以让您大致了解正在发生的事情。在执行发布版本生成时编译为空
所以,对于单元测试,执行发布构建,它将不会调用qFatal。-DqFatal=qCritical:)在某些情况下,您可能无法超越qFatal并静默地继续,被测试组件可能处于这样的状态,即在几行之后无论如何都会发生崩溃。避免这种情况的一种方法是在测试代码的某个地方存根qFatal;) 然后您可以拥有一些自己的断言宏:
#define CUSTOM_QEXPECT_FAIL( method ) { bool failed = false;\
try { \
method ; \
}\
catch(...) { \
failed = true; \
} \
QVERIFY(failed); }
并在代码中使用它,如:
CUSTOM_QEXPECT_FAIL( testedObj->panicAtTheDisco() );
并不是说这是一种很好的方法,只是试图证明可以为这个问题做些什么
另外,我没有仔细阅读,所以您正在静态链接测试类。在这种情况下,存根可能不起作用,除非您将其构建到测试可执行文件中。谢谢,Kaleb。真臭。有点苛刻,但我想我只会使用预处理器从调试版本中排除“预期失败”测试,只针对发布版本进行测试。谢谢@Adam-我检查了github,但在那里找不到它,谷歌也没有在搜索结果中列出它。
CUSTOM_QEXPECT_FAIL( testedObj->panicAtTheDisco() );