aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eliasson <andreas.eliasson@qt.io>2023-05-23 14:56:09 +0200
committerAndreas Eliasson <andreas.eliasson@qt.io>2023-05-30 13:42:35 +0200
commitbd845c2050204eadbac76d35e5f8b012aade4b52 (patch)
tree87c9ed756878802a9de8016597c1a5edf5e8dff2 /src
parent79e46dd07c3b23f93caced2f443939e34ef515bc (diff)
Doc: Add section that shows how to separate qml tests from app logic
All the examples in the docs only show how to test qml code that is in the same file as the test cases. In most cases, you would want to separate your tests from the application logic. This patch describes how to achieve this using CMake. Fixes: QTBUG-112840 Pick-to: 6.5 6.4 6.2 Change-Id: I81e8dafa5ea389fb5efa777ee0e51c661754762f Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qmltest/TestCase.qml75
-rw-r--r--src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt42
-rw-r--r--src/qmltest/doc/snippets/modules_MyModule_MyButton.qml11
-rw-r--r--src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt30
-rw-r--r--src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml30
5 files changed, 188 insertions, 0 deletions
diff --git a/src/qmltest/TestCase.qml b/src/qmltest/TestCase.qml
index b7848a9fd7..191797f251 100644
--- a/src/qmltest/TestCase.qml
+++ b/src/qmltest/TestCase.qml
@@ -224,6 +224,81 @@ import "testlogger.js" as TestLogger
of \l Component, the \l createTemporaryObject() function can be used.
\sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test}
+
+ \section1 Separating tests from application logic
+
+ In most cases, you would want to separate your tests from the application
+ logic by splitting them into different projects and linking them.
+
+ For example, you could have the following project structure:
+
+ \badcode
+ .
+ | — CMakeLists.txt
+ | — src
+ | | — main.cpp
+ | — qml
+ | | — main.qml
+ | — modules
+ | | — MyModule
+ | | — MyButton.qml
+ | | — CMakeLists.txt
+ | — tests
+ | — UnitQMLTests
+ | — tst_testqml.qml
+ | — main.cpp
+ | — setup.cpp
+ | — setup.h
+ \endcode
+
+ Now, to test the \c modules/MyModule/MyButton.qml, create a library for
+ \c MyModule in \c modules/MyModule/CMakeLists.txt and link it to your
+ test project, \c tests/UnitQMLTests/CMakeLists.txt:
+
+ \if defined(onlinedocs)
+ \tab {build-qt-app}{tab-cmake-add-library}{modules/MyModule/MyButton.qml}{checked}
+ \tab {build-qt-app}{tab-cmake-link-against-library}{tests/UnitQMLTests/CMakeLists.txt}{}
+ \tabcontent {tab-cmake-add-library}
+ \else
+ \section1 Add library
+ \endif
+ \dots
+ \snippet modules_Mymodule_CMakeLists.txt add library
+ \dots
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-cmake-link-against-library}
+ \else
+ \section1 Link against library
+ \endif
+ \dots
+ \snippet tests_UnitQMLTests_CMakeLists.txt link against library
+ \dots
+ \if defined(onlinedocs)
+ \endtabcontent
+ \endif
+
+ Then, in your \c tests/UnitQMLTests/tst_testqml.qml, you can import your
+ \c modules/MyModule/MyButton.qml:
+
+ \if defined(onlinedocs)
+ \tab {test-qml}{tab-qml-import}{tests/UnitQMLTests/tst_testqml.qml}{checked}
+ \tab {test-qml}{tab-qml-my-button}{modules/MyModule/MyButton.qml}{}
+ \tabcontent {tab-qml-import}
+ \else
+ \section1 Import QML
+ \endif
+ \snippet tests_UnitQMLTests_tst_testqml.qml import
+ \if defined(onlinedocs)
+ \endtabcontent
+ \tabcontent {tab-qml-my-button}
+ \else
+ \section1 Define QML button
+ \endif
+ \snippet modules_MyModule_MyButton.qml define
+ \if defined(onlinedocs)
+ \endtabcontent
+ \endif
*/
diff --git a/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt
new file mode 100644
index 0000000000..ea33144beb
--- /dev/null
+++ b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.20)
+
+set(MODULE_NAME "SecondPlugin")
+project(${MODULE_NAME} LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick)
+
+file(GLOB QML_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
+source_group("Qml Files" FILES ${QML_SOURCES})
+
+# file(GLOB CPP_SOURCES *.cpp)
+# file(GLOB HPP_SOURCES *.h)
+//! [add library]
+qt_add_library(${MyModule} STATIC)
+
+qt6_add_qml_module(${MyModule}
+ URI ${MyModule}
+ VERSION 1.0
+ QML_FILES ${QML_SOURCES}
+ # SOURCES ${CPP_SOURCES} ${HPP_SOURCES}
+)
+//! [add library]
+set_target_properties(${MODULE_NAME} PROPERTIES
+ MACOSX_BUNDLE TRUE
+ WIN32_EXECUTABLE FALSE
+)
+
+
+target_link_libraries(${MODULE_NAME} PRIVATE
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+)
+
+target_include_directories(${MODULE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml
new file mode 100644
index 0000000000..7cf9a19f00
--- /dev/null
+++ b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml
@@ -0,0 +1,11 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+//! [define]
+import QtQuick
+import QtQuick.Controls
+
+Button {
+ width: 50; height: 50
+ onClicked: { width = 100; }
+}
+//! [define]
diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt
new file mode 100644
index 0000000000..c9ea6377fe
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.2)
+
+project(TestQML LANGUAGES CXX)
+
+enable_testing()
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTest Qml)
+find_package(Qt6 REQUIRED COMPONENTS QuickTest Qml)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+# no need to copy around qml test files for shadow builds - just set the respective define
+add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
+
+//! [link against library]
+add_executable(TestQML main.cpp
+ setup.cpp setup.h)
+
+add_test(NAME TestQML COMMAND TestQML)
+
+target_link_libraries(
+ TestQML
+ PRIVATE Qt6::QuickTest
+ PRIVATE Qt6::Qml
+ PRIVATE MyModule
+ PRIVATE MyModuleplugin
+)
+//! [link against library]
diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml
new file mode 100644
index 0000000000..c6e418d945
--- /dev/null
+++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml
@@ -0,0 +1,30 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+//! [import]
+import QtQuick
+import QtQuick.Controls
+
+import QtTest
+import MyModule
+
+Item {
+ width: 800; height: 600
+
+ MyButton {
+ id: myButton
+ anchors.centerIn: parent
+ }
+
+ TestCase {
+ name: "MyButton";
+ when: windowShown;
+
+ function test_clickToExpand() {
+ const widthBeforeClick = myButton.width;
+ mouseClick(myButton);
+ const widthAfterClick = myButton.width;
+ verify(widthBeforeClick < widthAfterClick);
+ }
+ }
+}
+//! [import]