c++qtqmlqt5qtestlib

qmltestcase can't find c++ class method


I have a simple application that runs successfully; however, I am having difficulties trying to run a test case with qmltest. From the documentation it shows to setup the main.cpp file with the QUICK_TEST_MAIN_WITH_SETUP call to initialize the QML engine context. There is a runtime message: QMetaObject::invokeMethod: No such method QObject::qmlEngineAvailable(QQmlEngine*) as well as a qwarn message: QWARN : example::case_1::test_case1() file: MouseQml.qml:44: ReferenceError: mouse is not defined. The QML test case can't find my Class member function mouse.clear(). Am I setting this up correctly?

main.cpp

#include <QtQuickTest/quicktest.h>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include "mousememory.h"

class Setup : public QObject
{

public:
    Setup() {}

public slots:
    void qmlEngineAvailable(QQmlEngine *engine)
    {
        QScopedPointer<MouseMemory> mouse(new MouseMemory);
        engine->rootContext()->setContextProperty("mouse", mouse.data());
    }
};

QUICK_TEST_MAIN_WITH_SETUP(example, Setup)

simplified MouseQML.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    id: root
    visible: true
    width: 500
    height: 500

    Row {
        id: tools

        Button {
            id: clear
            objectName: "clear"
            text: "Clear"
            onClicked: {
                canvas.clear()
            }
        }
    }

    Canvas {
        id: canvas
        anchors.top: tools.bottom
        width: 500
        height: 500
        property int lastX: 0
        property int lastY: 0

        function clear() {
            var ctx = getContext("2d")
            ctx.reset()
            canvas.requestPaint()
            mouse.clear()
        }

    }
}

tst_case_1.qml

import QtQuick 2.0
import QtTest 1.0
import "../app"

TestCase {
    name: "case_1"

    MouseQml {
        id: mainApp
    }

    function initTestCase() {
        var qmlClear = findChild(mainApp, "clear")
        tryCompare(qmlClear, "text", "Clear")
    }

    function cleanupTestCase() {
    }

    function test_case1() {
        var qmlClear = findChild(mainApp, "clear")
        mouseClick(qmlClear)
        //tryCompare(qmlClear, "text", "Clear")
    }

    function test_case() {

    }
}

console output

11:45:54: Starting MouseMonitor\build\ui_test\debug\ui_test...
QMetaObject::invokeMethod: No such method QObject::qmlEngineAvailable(QQmlEngine*)
********* Start testing of example *********
Config: Using QtTest library 5.11.2, Qt 5.11.2 (x86_64-little_endian-llp64 shared (dynamic) debug build; by MSVC 2015)
PASS   : example::case_1::initTestCase()
PASS   : example::case_1::test_case()
QWARN  : example::case_1::test_case1() file:///MouseQml.qml:44: ReferenceError: mouse is not defined
PASS   : example::case_1::test_case1()
PASS   : example::case_1::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 16ms
********* Finished testing of example *********

Solution

  • You have 2 errors:

    Considering the above, the solution is as follows:

    main.cpp

    #include "mousememory.h"
    
    #include <QtQuickTest>
    #include <QQmlEngine>
    #include <QQmlContext>
    
    class Setup : public QObject
    {
        Q_OBJECT
    public:
        using QObject::QObject;
    public slots:
    
    #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
        void applicationAvailable(){
        }
    #endif
        void qmlEngineAvailable(QQmlEngine *engine)
        {
            mouse.reset(new MouseMemory);
            engine->rootContext()->setContextProperty("mouse", mouse.data());
        }
    #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
        void cleanupTestCase(){
        }
    #endif
    private:
        QScopedPointer<MouseMemory> mouse;
    };
    QUICK_TEST_MAIN_WITH_SETUP(example, Setup)
    
    #include "main.moc"
    

    The complete example you find here.


    Note: In Qt 5.12 two slots have been added: