【问题标题】:How can I immediately fail an auto test if a warning occurs如果出现警告,如何立即使自动测试失败
【发布时间】:2020-03-24 09:04:52
【问题描述】:

我想在测试代码中打印警告时立即使任何自动测试失败,这样我就不会在输出中错过它并在以后出现奇怪的测试失败。

我想我可以为此使用qInstallMessageHandler()。我修改了here的例子:

#include <QtTest>

class AutoTest : public QObject
{
    Q_OBJECT

public:
    AutoTest();
    ~AutoTest();

private slots:
    void test_case1();

};

void warningMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    const char *file = context.file ? context.file : "";
    const char *function = context.function ? context.function : "";
    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtInfoMsg:
        fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtWarningMsg:
        fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        exit(1);
    case QtCriticalMsg:
        fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtFatalMsg:
        fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    }
}

AutoTest::AutoTest()
{
    qInstallMessageHandler(warningMessageHandler);
}

AutoTest::~AutoTest()
{

}

void AutoTest::test_case1()
{
    qWarning() << "This should cause the application to exit with code 1";
}

QTEST_APPLESS_MAIN(AutoTest)

#include "tst_autotest.moc"

但是,测试应用程序并没有按预期提前退出:

17:32:04: Starting /Users/mitch/dev/temp/autotest-qt5_14_fw-Debug/autotest.app/Contents/MacOS/autotest ...
********* Start testing of AutoTest *********
Config: Using QtTest library 5.14.0, Qt 5.14.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by Clang 10.0.0 (clang-1000.11.45.2) (Apple))
PASS   : AutoTest::initTestCase()
QWARN  : AutoTest::test_case1() This should cause the application to exit
PASS   : AutoTest::test_case1()
PASS   : AutoTest::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 2ms
********* Finished testing of AutoTest *********
17:32:04: /Users/mitch/dev/temp/autotest-qt5_14_fw-Debug/autotest.app/Contents/MacOS/autotest exited with code 0

我在消息处理函数中设置了一个断点,但它没有被命中一次。怎么回事?

【问题讨论】:

    标签: c++ qt qttest


    【解决方案1】:

    虽然文档中的示例显示处理程序安装在main() 的开头,但这对于自动测试来说是不够的。似乎 Qt 本身在自动测试的生命周期中安装了其他消息处理程序,并且这些处理程序的安装时间比测试的构造函数晚了很多。如果您通过放置断点 here 从源代码构建 Qt,您可以自己验证这一点。

    一旦创建测试本身(在QTEST_APPLESS_MAIN 宏内),Qt 的测试日志基础架构就会安装自己的消息处理程序。

    如果您在 Creator 中使用 QML 调试,那么它也会安装自己的消息处理程序。

    要解决这个问题,请尽可能晚地安装您的处理程序:

    #include <QtTest>
    
    class AutoTest : public QObject
    {
        Q_OBJECT
    
    public:
        AutoTest();
        ~AutoTest();
    
    private slots:
        void initTestCase();
        void test_case1();
    
    };
    
    static QtMessageHandler oldMessageHandler;
    
    // Exits on warnings
    void warningMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    {
        QByteArray localMsg = msg.toLocal8Bit();
        const char *file = context.file ? context.file : "";
        const char *function = context.function ? context.function : "";
        switch (type) {
        case QtWarningMsg:
            fprintf(stderr, "EXITING - TEST FAILED DUE TO WARNING: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
            exit(1);
        default:
            oldMessageHandler(type, context, msg);
        }
    }
    
    AutoTest::AutoTest()
    {
    }
    
    AutoTest::~AutoTest()
    {
    
    }
    
    void AutoTest::initTestCase()
    {
        oldMessageHandler = qInstallMessageHandler(warningMessageHandler);
    }
    
    void AutoTest::test_case1()
    {
        qWarning() << "This should cause the application to exit with code 1";
    }
    
    QTEST_APPLESS_MAIN(AutoTest)
    
    #include "tst_autotest.moc"
    

    请务必调用之前安装的消息处理程序,以免丢失 Qt 日志记录提供的任何功能。

    这个输出:

    17:44:44: Starting /Users/mitch/dev/temp/autotest-qt5_14_fw-Debug/autotest.app/Contents/MacOS/autotest ...
    ********* Start testing of AutoTest *********
    Config: Using QtTest library 5.14.0, Qt 5.14.0 (x86_64-little_endian-lp64 shared (dynamic) debug build; by Clang 10.0.0 (clang-1000.11.45.2) (Apple))
    EXITING - TEST FAILED DUE TO WARNING: This should cause the application to exit with code 1 (../autotest/tst_autotest.cpp:50, void AutoTest::test_case1())
    PASS   : AutoTest::initTestCase()
    17:44:44: /Users/mitch/dev/temp/autotest-qt5_14_fw-Debug/autotest.app/Contents/MacOS/autotest exited with code 1
    

    【讨论】:

      猜你喜欢
      • 2023-01-31
      • 2020-06-19
      • 2018-08-24
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 2018-07-04
      相关资源
      最近更新 更多