-
Qml unit test
I want to test complex qml gui using QuickTest framewrok. The C++ portion of the code is very short:
#include <QtQuickTest/quicktest.h>
QUICK_TEST_MAIN(QmlFormToBeTested)
The qml document looks like this:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtGraphicalEffects 1.0
import CalcCritRangeSetup 1.0
import CfgEnableTable 1.0
import PrecisionHelper 1.0
import UnitsSetupTable 1.0
Rectangle
{
id: criticalRanges
width: sys.width
height: sys.height
color: sys.screen_background_color
property int lowEntryError: 0
property int highEntryError: 0
property string enableState: ""
property variant selectedInput: null
property variant selectedRectangle: null
property int selectedType: -1
property bool changeMade: false
property bool canEdit: false
property bool showKeyboard: false
property string selectedParameter: ""
...
The following import modules are from database models that are needed for the view:
CalcCritRangeSetup 1.0
CfgEnableTable 1.0
PrecisionHelper 1.0
UnitsSetupTable 1.0
In other words, the qml file is coupled with other c++ code. In real application, the main c++ will initialized the database, and register these database model and use them in qml code, and all works fine.
I try to use the QUICK_TEST_MAIN(QmlFormToBeTested) to test the qml file. As the main is generated by macro, and can't use c++ code to register model for qml use. So was wondering if anyone has suggestions for this ? Is it ok to generate a QmlGuiInit Plugin that include all the initialization and registration of the models? or perhaps other suggestions for this kind of complex qml gui unit test?
Thanks in advance,
Alex
-
Re: Qml unit test
Maybe make a C++ test program that does the proper stack initialization, then loads the file and then calls the test methods itself.
Cheers,
_
-
Re: Qml unit test
Hi anda_skoa:
I assume you suggest something similar to plugin approach, use c++ to initialize, and import the plugin to qml doc.
I tried this approach, and successfully build the following two files and put these two files in /usr/lib/qt5/qml/GuiTestInit/ folder:
libqmlguitestplugin.so
qmldir
The plugin.cpp is stub for now:
#include <QDebug>
#include <QtQuick>
#include <QtQml/qqml.h>
#include <QtQml/QQmlExtensionPlugin>
#include <QGuiApplication>
#include <QQuickItem>
#include <QQuickWindow>
class GuiInit: public QObject
{
Q_OBJECT
private:
GuiInit( QObject* parent = NULL );
static GuiInit* db_inst;
// DatabaseThread* m_database_thread;
QList<QObject*> initialized_databases;
public:
static GuiInit* instance( QObject* parent = NULL );
~GuiInit( void );
void initAll();
};
class GuiTestInitModel : public QObject
{
Q_OBJECT
public:
GuiTestInitModel(QObject *parent=0) : QObject(parent)
{
}
~GuiTestInitModel()
{
}
Q_INVOKABLE int init(const QString &msg)
{
return 0;
}
public:
};
class GuiTestInitPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA( IID "org.qt-project.Qt.QQmlExtensionPlugin" FILE "qmlguitestinit.json" );
public:
void registerTypes(const char *uri)
{
qmlRegisterType<GuiTestInitModel>(uri, 1, 0, "GuiTestInit");
}
Q_INVOKABLE void databaseInit( void )
{
}
};
#include "plugin.moc"
When testing using a simple qml:
import QtQuick 2.3
import QtTest 1.0
import GuiTestInit 1.0
Rectangle {
id: backgroundRec
visible: true
width: 1024
height: 600
Text
{
text: qsTr("Hello World")
anchors.centerIn: parent
font.family: "Helvetica"
font.pointSize: 24
}
Rectangle
{
id: testButton
width: 224
height: 60
anchors.top: parent.top
anchors.topMargin: 100
anchors.left: parent.left
anchors.leftMargin: 400
Text
{
id: backText
width: paintedWidth
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "black"
text: qsTr( "Test" )
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pointSize: 20
MouseArea
{
anchors.fill: parent
onPressed: { backText.opacity = 0.3 }
onReleased: { backText.opacity = 1.0 }
}
}
}
TestCase {
name: "StartupTest"
function test_backgroundRec() {
compare(backgroundRec.width, 1024)
compare(backgroundRec.height, 600)
compare(backgroundRec.visible, true)
}
function test_button() {
compare(testButton.width, 224)
compare(testButton.height, 60)
}
}
}
When running the test application, I got the following error:
./tst_calculatedCriticalRangesFormTest_opti -platform eglfs
file:///home/root/gui_tests/calculatedCriticalRangesFormTest/tst_calculatedCriticalRangesFormTest.qml:12:1: plugin cannot be loaded for module "GuiTestInit": Cannot load library /usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: (/usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: undefined symbol: _ZN7GuiInitD1Ev)
import GuiTestInit 1.0
^
********* Start testing of tst_calculatedCriticalRangesFormTest *********
Config: Using QtTest library 5.3.2, Qt 5.3.2
QWARN : tst_calculatedCriticalRangesFormTest::tst_calculat edCriticalRangesFormTest::compile()
/home/root/gui_tests/calculatedCriticalRangesFormTest/tst_calculatedCriticalRangesFormTest.qml produced 1 error(s):
/home/root/gui_tests/calculatedCriticalRangesFormTest/tst_calculatedCriticalRangesFormTest.qml:12,1: plugin cannot be loaded for module "GuiTestInit": Cannot load library /usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: (/usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: undefined symbol: _ZN7GuiInitD1Ev)
Working directory: /home/root/gui_tests/calculatedCriticalRangesFormTest
View: QQuickView, import paths:
'/home/root/gui_tests/calculatedCriticalRangesFormTest'
'/usr/lib/qt5/qml'
Plugin paths:
'.'
FAIL! : tst_calculatedCriticalRangesFormTest::tst_calculat edCriticalRangesFormTest::compile() plugin cannot be loaded for module "GuiTestInit": Cannot load library /usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: (/usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: undefined symbol: _ZN7GuiInitD1Ev)
Loc: [/home/root/gui_tests/calculatedCriticalRangesFormTest/tst_calculatedCriticalRangesFormTest.qml(12)]
Totals: 0 passed, 1 failed, 0 skipped
********* Finished testing of tst_calculatedCriticalRangesFormTest *********
Can anyone tell me why plugin load error?
Thanks,
Alex
-
Re: Qml unit test
Another way of having c++ initialization is to customize the QUICK_TEST_MAIN with c++ main() and add my data model portion, was wondering if this is a feasible approach, and what will be the source code or sample for this approach?
-
Qt Plugin error
I have a QML plugin build successfully, but during run time, I have the following error:
plugin cannot be loaded for module "GuiTestInit": Cannot load library /usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: (/usr/lib/qt5/qml/GuiTestInit/libqmlguitestplugin.so: undefined symbol: _ZN7GuiInitD1Ev)
Could anyone help on this ?
Thanks,
Alex
-
Re: Qml unit test
Do all of the methods you declared have implementations?
Anyway, I would have simply created a test program, but if you want to use a plugin approach, why not.
Cheers,
_
and please use [code][/code] tags!