本页内容

TestCase QML Type

表示一个单元测试用例。更多...

Import Statement: import QtTest
Inherits:

Item

属性

方法

详细说明

QML 测试用例简介

测试用例以 JavaScript 函数的形式编写在 TestCase 类型中:

import QtQuick 2.0
import QtTest 1.2

TestCase {
    name: "MathTests"

    function test_math() {
        compare(2 + 2, 4, "2 + 2 = 4")
    }

    function test_fail() {
        compare(2 + 2, 5, "2 + 2 = 5")
    }
}

名称以“test_”开头的函数将被视为待执行的测试用例。name 属性用于在输出中为这些函数添加前缀:

********* Start testing of MathTests *********
Config: Using QTest library 4.7.2, Qt 4.7.2
PASS   : MathTests::initTestCase()
FAIL!  : MathTests::test_fail() 2 + 2 = 5
   Actual (): 4
   Expected (): 5
   Loc: [/home/.../tst_math.qml(12)]
PASS   : MathTests::test_math()
PASS   : MathTests::cleanupTestCase()
Totals: 3 passed, 1 failed, 0 skipped
********* Finished testing of MathTests *********

由于 JavaScript 属性的工作原理,测试函数被查找的顺序是不可预测的。为了提高可预测性,测试框架会按函数名称升序对函数进行排序。当有两个必须按顺序运行的测试时,这会非常有用。

可以提供多种 TestCase 类型。一旦所有测试都完成,测试程序将退出。

数据驱动测试

可以通过名称以“_data”结尾的函数向测试提供表格数据。此外,还可以使用 `init_data() ` 函数,为 TestCase 类型中没有匹配的“_data”函数的所有测试函数提供默认测试数据:

import QtQuick 2.0
import QtTest 1.2

TestCase {
    name: "DataTests"

    function init_data() {
      return [
           {tag:"init_data_1", a:1, b:2, answer: 3},
           {tag:"init_data_2", a:2, b:4, answer: 6}
      ];
    }

    function test_table_data() {
        return [
            {tag: "2 + 2 = 4", a: 2, b: 2, answer: 4 },
            {tag: "2 + 6 = 8", a: 2, b: 6, answer: 8 },
        ]
    }

    function test_table(data) {
        //data comes from test_table_data
        compare(data.a + data.b, data.answer)
    }

    function test_default_table(data) {
        //data comes from init_data
        compare(data.a + data.b, data.answer)
    }
}

测试框架将遍历表中的所有行,并将每行传递给测试函数。如示例所示,可以提取列内容供测试使用。tag 列具有特殊作用——当某行测试失败时,测试框架会打印该列内容,以帮助读者在一组通过的测试中识别出哪个测试用例失败。

基准测试

名称以“benchmark_”开头的函数将通过 Qt 基准测试框架多次运行,并报告各次运行的平均耗时。这相当于在 QTestLib 的 C++ 版本中使用QBENCHMARK 宏。

TestCase {
    id: top
    name: "CreateBenchmark"

    function benchmark_create_component() {
        let component = Qt.createComponent("item.qml")
        let obj = component.createObject(top)
        obj.destroy()
        component.destroy()
    }
}

RESULT : CreateBenchmark::benchmark_create_component:
     0.23 msecs per iteration (total: 60, iterations: 256)
PASS   : CreateBenchmark::benchmark_create_component()

若要获得与QBENCHMARK_ONCE 宏相同的效果,请在测试函数名前添加前缀“benchmark_once_”。

模拟键盘和鼠标事件

keyPress()、keyRelease() 和keyClick() 方法可用于在单元测试中模拟键盘事件。这些事件将传递给当前获得焦点的 QML 项。您可以传入 Qt.Key 枚举值或 latin1 字符(长度为 1 的字符串)。

Rectangle {
    width: 50; height: 50
    focus: true

    TestCase {
        name: "KeyClick"
        when: windowShown

        function test_key_click() {
            keyClick(Qt.Key_Left)
            keyClick("a")
            ...
        }
    }
}

mousePress()、mouseRelease()、mouseClick()、mouseDoubleClickSequence() 和mouseMove() 方法可用于以类似的方式模拟鼠标事件。

如果您的测试创建了其他窗口,这些窗口可能会成为活动窗口,从而夺走 TestCase 窗口的焦点。为确保 TestCase 窗口处于活动状态,请使用以下代码:

testCase.Window.window.requestActivate()
tryCompare(testCase.Window.window, "active", true)

注意:只有在主窗口显示后,才能发送键盘和鼠标事件。在此之前尝试发送事件将失败。请使用when 和windowShown 属性来跟踪主窗口何时显示。

管理动态创建的测试对象

QML 测试中的一种典型模式是动态创建一个项目,然后在测试函数结束时将其销毁:

TestCase {
    id: testCase
    name: "MyTest"
    when: windowShown

    function test_click() {
        let item = Qt.createQmlObject("import QtQuick 2.0; Item {}", testCase);
        verify(item);

        // Test item...

        item.destroy();
    }
}

这种模式的问题在于,测试函数中的任何失败都会导致跳过对 `item.destroy() ` 的调用,从而使该项一直留在场景中,直到测试用例结束。这可能会干扰后续测试;例如,阻塞输入事件或产生无关的调试输出,从而难以追踪代码的执行过程。

若改为调用createTemporaryQmlObject(),则可确保该对象在测试函数结束时被销毁:

TestCase {
    id: testCase
    name: "MyTest"
    when: windowShown

    function test_click() {
        let item = createTemporaryQmlObject("import QtQuick 2.0; Item {}", testCase);
        verify(item);

        // Test item...

        // Don't need to worry about destroying "item" here.
    }
}

对于通过Component 的createObject()函数创建的对象,可以使用createTemporaryObject()函数。

将测试与应用程序逻辑分离

在大多数情况下,您会希望将测试与应用程序逻辑分离,方法是将它们拆分为不同的项目并相互关联。

例如,您可以采用以下项目结构:

.
| — CMakeLists.txt
| — main.cpp
| - main.qml
| — MyModule
    | — MyButton.qml
    | — CMakeLists.txt
| — tests
    | — tst_testqml.qml
    | — main.cpp
    | — setup.cpp
    | — setup.h

现在,要测试MyModule/MyButton.qml ,请在MyModule/CMakeLists.txt 中为MyModule 创建一个库,并将其链接到您的测试项目tests/UnitQMLTests/CMakeLists.txt :

    ...
qt_add_library(MyModule STATIC)

qt6_add_qml_module(MyModule
    URI MyModule
    QML_FILES MyButton.qml
)
    ...
#include <QtQuickTest/quicktest.h>
#include "setup.h"

QUICK_TEST_MAIN_WITH_SETUP(TestQML, Setup)
#include "setup.h"

void Setup::applicationAvailable()
{
    // custom code that doesn't require QQmlEngine
}

void Setup::qmlEngineAvailable(QQmlEngine *engine)
{
    // add import paths
}

void Setup::cleanupTestCase()
{
    // custom code to clean up before destruction starts
}
#ifndef SETUP_H
#define SETUP_H

#include <QObject>
#include <QQmlEngine>

class Setup : public QObject
{
    Q_OBJECT
public:
    Setup() = default;

public slots:
    void applicationAvailable();
    void qmlEngineAvailable(QQmlEngine *engine);
    void cleanupTestCase();
};

#endif // SETUP_H
    ...
add_subdirectory(MyModule)
add_subdirectory(tests)

qt_add_executable(MyApplication
    src/main.cpp
)

qt_add_qml_module(MyApplication
    URI MyApplication
    QML_FILES main.qml
)
    ...

然后,在 `tests/tst_testqml.qml` 中,你可以导入 `MyModule/MyButton.qml`:

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 QtQuick
import QtQuick.Controls

Button {
    width: 50
    height: 50
    onClicked: width = 100
}

另请参阅 SignalSpy 以及 Qt Quick Test。

属性文档

completed : bool

该属性将在测试用例执行完成后被设置为 true。测试用例仅执行一次。初始值为 false。

另请参阅 running 和when 。

name : string

此属性用于定义结果报告中测试用例的名称。默认值为空字符串。

TestCase {
    name: "ButtonTests"
    ...
}

running : bool

在测试用例运行期间,该属性将被设置为 true。初始值为 false,测试用例完成后,该值将再次变为 false。

另请参阅 completed 和when 。

when : bool

当应用程序希望运行测试用例时,应将此属性设置为 true。默认值为 true。在下面的示例中,当用户按下鼠标按钮时,将运行一个测试:

Rectangle {
    id: foo
    width: 640; height: 480
    color: "cyan"

    MouseArea {
        id: area
        anchors.fill: parent
    }

    property bool bar: true

    TestCase {
        name: "ItemTests"
        when: area.pressed
        id: test1

        function test_bar() {
            verify(bar)
        }
    }
}

一旦所有TestCase 类型的测试被触发并执行完毕,测试应用程序将退出。

另请参阅 completed 。

windowShown : bool

在 QML 查看窗口显示后,该属性将被设置为 true。通常,测试用例会在测试应用程序加载后、窗口显示之前立即运行。如果测试用例涉及视觉元素和行为,则可能需要延迟运行,直到窗口显示之后。

Button {
    id: button
    onClicked: text = "Clicked"
    TestCase {
        name: "ClickTest"
        when: windowShown
        function test_click() {
            button.clicked();
            compare(button.text, "Clicked");
        }
    }
}

方法文档

cleanup()

在TestCase 类型中,每执行一次测试函数后都会调用此函数。默认实现不执行任何操作。应用程序可以提供自己的实现,以便在每次测试函数执行后进行清理。

另请参阅 init() 和cleanupTestCase()。

cleanupTestCase()

当TestCase 类型中的所有其他测试函数执行完毕后,将调用此函数。默认实现不执行任何操作。应用程序可以提供自己的实现来执行测试用例的清理工作。

另请参阅 initTestCase() 和cleanup()。

compare(actual, expected, message = "")

如果actual 与expected 不一致,则当前测试用例将失败,并显示可选的message 信息。这与 C++ 中的QCOMPARE(actual, expected) 类似。

另请参阅 tryCompare() 和fuzzyCompare 。

QtObject createTemporaryObject(Component component, QtObject parent, var properties)

该函数根据给定的component ,结合指定的可选参数parent 和properties ,动态创建一个QML对象。在cleanup()执行完毕后,该返回的对象将被销毁(如果尚未被销毁的话),这意味着使用该函数创建的对象在每次测试结束后都会被保证销毁,无论测试是否失败。

如果在创建对象时发生错误,将返回null 。

该函数会在内部调用component.createObject()。

另请参阅 Managing Dynamically Created Test Objects 。

QtObject createTemporaryQmlObject(string qml, QtObject parent, string filePath)

该函数根据给定的qml 字符串和指定的parent ,动态创建一个QML对象。在cleanup()执行完毕后,该返回的对象将被销毁(如果尚未被销毁的话),这意味着使用该函数创建的对象在每次测试结束后都保证会被销毁,无论测试是否失败。

如果在创建对象时发生错误,将返回null 。

如果指定了filePath ,它将用于创建对象的错误报告。

该函数在内部调用Qt.createQmlObject()。

另请参阅 Managing Dynamically Created Test Objects 。

expectFail(tag, message)

在数据驱动测试中,将与tag 关联的行标记为预期会失败。当发生失败时,显示message ,中止测试,并将测试标记为通过。这类似于C++中的QEXPECT_FAIL(tag, message, Abort) 。

如果测试不是数据驱动的,则必须将 `tag ` 设置为空字符串。

另请参阅 expectFailContinue()。

expectFailContinue(tag, message)

在数据驱动测试中,将与tag 关联的行标记为预期会失败。当测试失败时,显示message ,然后继续执行测试。这与C++中的QEXPECT_FAIL(tag, message, Continue) 类似。

如果测试不是数据驱动的,则必须将 `tag ` 设置为空字符串。

另请参阅 expectFail()。

fail(message = "")

使当前测试用例失败,并返回可选的message 。这与 C++ 中的QFAIL(message) 类似。

[since 6.3] failOnWarning(message)

对于每个符合message 条件的警告,都会在测试日志中追加一条测试失败记录。添加失败记录后,测试函数将继续执行。

message 可以是字符串,也可以是提供消息模式的正则表达式。在后一种情况下,对于遇到的每个警告,第一个匹配的模式将导致失败,其余模式将被忽略。

每个测试函数结束时,所有模式都会被清除。

例如,如果出现文本为“Something bad happened”的警告,以下代码片段将导致测试失败:

failOnWarning("Something bad happened")

如果遇到任何与给定模式匹配的警告,以下代码片段将导致测试失败:

failOnWarning(/[0-9]+ bad things happened/)

若要使所有触发特定警告的测试均失败,请在 `init()` 中向该函数传递一个合适的正则表达式:

function init() {
    failOnWarning(/.?/)
}

注意:尽管 它是 JavaScript RegExp 对象,但不会被作为 RegExp 对象解释;相反,该模式将被传递给 `QRegularExpression`。

注意:`ignoreMessage ()` 的优先级高于此函数,因此任何同时匹配 `ignoreMessage() ` 和 `failOnWarning() ` 中给定模式的警告都将被忽略。

此方法在 Qt 6.3 中引入。

另请参阅 QTest::failOnWarning() 和warn()。

QtObject findChild(parent, objectName)

返回parent 中符合objectName 条件的第一个子节点;如果不存在此类项,则返回null 。系统会递归搜索视觉和非视觉子节点,其中优先搜索视觉子节点。

compare(findChild(item, "childObject"), expectedChildObject);

fuzzyCompare(actual, expected, delta, message = "")

如果actual 与expected 之间的差值大于delta ,则当前测试用例失败,并显示可选的message 。这与 C++ 中的qFuzzyCompare(actual, expected) 类似,但要求delta 必须为非零值。

如果actual 和expected 这两个值均可转换为颜色值,则该函数也可用于颜色比较。如果 RGBA 通道值中的任何一个差异大于delta ,则测试失败。

另请参阅 tryCompare() 和compare()。

QtObject grabImage(Item item)

返回给定item 的快照图像对象。

返回的图像对象具有以下属性:

  • width 返回底层图像的宽度(自 5.10 起)
  • height 返回底层图像的高度(自 5.10 起)
  • size 返回底层图像的大小(自 5.10 起)

此外,返回的图像对象还具有以下方法:

  • red(x, y) 返回坐标为x、y的像素的红色通道值
  • green(x, y) 返回位于x,y位置的像素的绿色通道值
  • blue(x, y) 返回位于x、y位置的像素的蓝色通道值
  • alpha(x, y) 返回坐标为x,y的像素的 alpha 通道值
  • pixel(x, y) 返回位于x、y位置的像素的颜色值
  • equals(image) 如果该图像与image完全相同,则返回 `true `——详见QImage::operator== (自 5.6 版起)

    例如:

    let image = grabImage(rect);
    compare(image.red(10, 10), 255);
    compare(image.pixel(20, 20), Qt.rgba(255, 0, 0, 255));
    
    rect.width += 10;
    let newImage = grabImage(rect);
    verify(!newImage.equals(image));
  • save(path) 将图像保存到指定路径。如果无法保存图像,将抛出异常。(自 5.10 起)

    这对于对失败的测试进行事后分析非常有用,例如:

    let image = grabImage(rect);
    try {
        compare(image.width, 100);
    } catch (ex) {
        image.save("debug.png");
        throw ex;
    }

ignoreWarning(message)

将message 标记为被忽略的警告消息。当该警告出现时,系统不会显示该警告,且测试通过。如果未出现该警告,则测试失败。类似于 C++ 中的QTest::ignoreMessage(QtWarningMsg, message) 。

自 Qt 5.12 起,message 可以是字符串,也可以是提供要忽略的消息模式的正则表达式。

例如,以下代码片段将忽略一条字符串形式的警告消息:

ignoreWarning("Something sort of bad happened")

而以下代码片段将忽略符合正则表达式模式的若干可能的警告消息:

ignoreWarning(new RegExp("[0-9]+ bad things happened"))

注意:尽管 它是 JavaScript 的 RegExp 对象,但不会被作为正则表达式进行解析;相反,该模式将直接传递给QRegularExpression 函数。

另请参阅 warn()。

init()

在TestCase 类型中,每次执行测试函数之前都会调用此函数。默认实现不执行任何操作。应用程序可以提供自己的实现,以便在每次测试函数执行前进行初始化。

另请参阅 cleanup() 和initTestCase()。

initTestCase()

该函数会在TestCase 类型中的任何其他测试函数之前被调用。默认实现不执行任何操作。应用程序可以提供自己的实现来执行测试用例的初始化。

另请参阅 cleanupTestCase() 和init()。

bool isPolishScheduled(object itemOrWindow)

如果 `itemOrWindow ` 是一个 `Item`,当自上次调用 `polish()` 以来尚未对其调用 `updatePolish()` 时,该函数返回 `true `;否则返回 `false`。

自 Qt 6.5 起,如果itemOrWindow 是Window ,当自上次对该项调用polish() 以来,其管理的任何项均未被调用updatePolish() 时,该函数返回true ;否则返回false 。

在 QML 中为属性赋值时,项目因赋值而需要进行的任何布局调整可能不会立即生效,而是会被推迟到项目完成“polish”操作之后。对于此类情况,您可以使用此函数来确保在测试执行继续之前,项目已完成“polish”操作。例如:

verify(isPolishScheduled(item))
verify(waitForItemPolished(item))

如果上文未调用isPolishScheduled() ,则waitForItemPolished() 可能会检测到未安排任何完善操作,从而立即通过测试——这假设该项已经过完善。此函数能清晰说明项目未被完善的原因,并允许测试在此类情况下尽早失败。

另请参阅 waitForPolish()、QQuickItem::polish() 和QQuickItem::updatePolish()。

keyClick(key, modifiers = Qt.NoModifier, delay = -1)

模拟点击key ,并可选地对当前焦点所在的项目执行modifiers 操作。如果delay 大于 0,则测试将等待delay 毫秒。

有关支持的key 格式的更多信息,请参阅Simulating Keyboard and Mouse Events 。

该事件将发送至TestCase 窗口;若有多个窗口,则发送至当前活动窗口。更多详细信息请参阅QGuiApplication::focusWindow()。

另请参阅 keyPress() 和keyRelease()。

keyPress(key, modifiers = Qt.NoModifier, delay = -1)

模拟在当前焦点所在的项目上按下key ,并可选地按下modifiers 。如果delay 大于0,则测试将等待delay 毫秒。

有关支持的key 格式的更多信息,请参阅Simulating Keyboard and Mouse Events 。

该事件将发送至TestCase 窗口;若有多个窗口,则发送至当前活动窗口。更多详细信息请参阅QGuiApplication::focusWindow()。

注意:在某个时刻,您应通过keyRelease() 释放该键。

另请参阅 keyRelease() 和keyClick()。

keyRelease(key, modifiers = Qt.NoModifier, delay = -1)

模拟在当前焦点项上释放key ,并可选地设置modifiers 。如果delay 大于0,则测试将等待delay 毫秒。

有关支持的key 格式的更多信息,请参阅Simulating Keyboard and Mouse Events 。

该事件将发送至TestCase 窗口;若有多个窗口,则发送至当前活动窗口。更多详情请参阅QGuiApplication::focusWindow()。

另请参阅 keyPress() 和keyClick()。

keySequence(keySequence)

模拟输入keySequence 。键序列可以设置为standard keyboard shortcuts 中的任意一种,也可以用一个字符串来描述,该字符串包含最多四个按键的按压序列。

每个事件应发送至TestCase 窗口;若存在多个窗口,则发送至当前活动窗口。更多详情请参见QGuiApplication::focusWindow()。

另请参阅 keyPress()、keyRelease()、GNU Emacs Style Key Sequences 以及Shortcut.sequence 。

mouseClick(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上点击鼠标button ,可选modifiers 。点击位置由x 和y 定义。如果未定义x 和y ,则位置将设为item 的中心。如果指定了delay ,测试将在按下和释放按钮前分别等待指定的毫秒数。

由x 和y 指定的位置会从item 的坐标系转换为窗口坐标,然后进行传递。如果item 被另一个控件遮挡,或者item 的某个子控件占据了该位置,则事件将转而传递给该控件。

另请参阅 mousePress()、mouseRelease()、mouseDoubleClickSequence()、mouseMove()、mouseDrag() 以及mouseWheel()。

mouseDoubleClickSequence(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上双击鼠标button 时生成的完整事件序列,可选modifiers 。

该方法重现了用户进行双击时生成的鼠标事件序列:按下-释放-按下-双击-释放。

点击位置由x 和y 定义。如果未定义x 和y ,则位置将设为item 的中心。如果指定了delay ,测试将在按下和释放按钮前等待指定的毫秒数。

由x 和y 给定的位置会从item 的坐标系转换为窗口坐标,然后进行分发。如果item 被另一个控件遮挡,或者item 的某个子控件占据了该位置,则事件将转而分发给该控件。

此 Qml 方法在 Qt 5.5 中引入。

另请参阅 mousePress()、mouseRelease()、mouseClick()、mouseMove()、mouseDrag() 以及mouseWheel()。

mouseDrag(item, x, y, dx, dy, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上按住button 并可选modifiers 的情况下拖动鼠标。初始拖动位置由x 和y 定义,拖动距离由dx 和dy 定义。如果指定了delay ,测试将在释放按钮前等待指定数量的毫秒。

由x 和y 给出的位置会从item 的坐标系转换为窗口坐标,然后进行传递。如果item 被另一个控件遮挡,或者item 的某个子控件占据了该位置,则该事件将转而传递给该控件。

另请参阅 mousePress()、mouseClick()、mouseDoubleClickSequence()、mouseMove()、mouseRelease() 以及mouseWheel()。

mouseMove(item, x = item.width / 2, y = item.height / 2, delay = -1, buttons = Qt.NoButton)

将鼠标指针移动到由x 和y 指定的位置(位于item 内),同时若指定了buttons ,则保持按住该键。自 Qt 6.0 起,如果未定义x 和y ,则位置将设为item 的中心。

如果提供了delay (单位为毫秒),则测试会在移动鼠标指针前进行等待。

由x 和y 指定的位置会从item 的坐标系转换为窗口坐标,然后传递出去。如果item 被另一个项目遮挡,或者item 的某个子项占据了该位置,则该事件将转而传递给另一个项目。

另请参阅 mousePress()、mouseRelease()、mouseClick()、mouseDoubleClickSequence()、mouseDrag() 以及mouseWheel()。

mousePress(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上点击鼠标button ,并可选地同时点击modifiers 。位置由x 和y 定义。如果未定义x 或y ,则位置将设为item 的中心。如果指定了delay ,则测试将在点击前等待指定的毫秒数。

由x 和y 给出的位置会从item 的坐标系转换为窗口坐标,然后进行分发。如果item 被另一个元素遮挡,或者item 的某个子元素占据了该位置,则该事件将转而分发给该元素。

另请参阅 mouseRelease()、mouseClick()、mouseDoubleClickSequence()、mouseMove()、mouseDrag() 以及mouseWheel()。

mouseRelease(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上释放鼠标button ,并可选地设置modifiers 。释放位置由x 和y 定义。如果未定义x 或y ,则位置将为item 的中心。如果指定了delay ,测试将在等待指定的毫秒数后释放按钮。

由x 和y 提供的坐标会从item 的坐标系转换为窗口坐标,然后传递出去。如果item 被另一个元素遮挡,或者item 的某个子元素占据了该位置,则该事件将转而传递给该其他元素。

另请参阅 mousePress()、mouseClick()、mouseDoubleClickSequence()、mouseMove()、mouseDrag() 以及mouseWheel()。

mouseWheel(item, x, y, xDelta, yDelta, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)

模拟在item 上滚动鼠标滚轮,同时按下button ,并可选地按下modifiers 。滚轮事件的位置由x 和y 定义。如果指定了delay ,测试将在释放按钮前等待指定的毫秒数。

由x 和y 给出的位置,会从item 的坐标系转换为窗口坐标,然后传递出去。如果item 被另一个控件遮挡,或者item 的某个子控件占据了该位置,则该事件将转而传递给该控件。

xDelta 和yDelta 包含以八分之一度为单位的滚轮旋转距离。更多详细信息请参见QWheelEvent::angleDelta()。

另请参阅 mousePress()、mouseClick()、mouseDoubleClickSequence()、mouseMove()、mouseRelease()、mouseDrag() 以及QWheelEvent::angleDelta()。

skip(message = "")

跳过当前测试用例,并输出可选的message 。如果是数据驱动测试,则仅跳过当前行。类似于 C++ 中的QSKIP(message) 。

sleep(ms)

暂停处理 Qt XML 事件,休眠ms 毫秒。

另请参阅 wait() 和waitForRendering()。

TouchEventSequence touchEvent(object item)

通过模拟触摸屏(QPointingDevice )触发一系列触摸事件。事件将传递给包含item 的窗口。

返回的对象用于枚举将通过单个QTouchEvent 传递的事件。除非另有说明,否则触摸事件将传递给包含TestCase 的窗口。

Rectangle {
    width: 640; height: 480

    MultiPointTouchArea {
        id: area
        anchors.fill: parent

        property bool touched: false

        onPressed: touched = true
    }

    TestCase {
        name: "ItemTests"
        when: windowShown
        id: test1

        function test_touch() {
            let touch = touchEvent(area);
            touch.press(0, area, 10, 10);
            touch.commit();
            verify(area.touched);
        }
    }
}

另请参阅 TouchEventSequence::press()、TouchEventSequence::move()、TouchEventSequence::release()、TouchEventSequence::stationary()、TouchEventSequence::commit() 以及QInputDevice::DeviceType 。

tryCompare(obj, property, expected, timeout = 5000, message = "")

如果obj 上的指定property 与expected 不一致,则当前测试用例将失败,并显示可选的message 。该测试将多次重试,直到达到timeout (以毫秒为单位)为止。

此函数旨在测试那些属性值会根据异步事件发生变化的应用程序。若要测试同步属性变化,请使用compare()。

tryCompare(img, "status", BorderImage.Ready)
compare(img.width, 120)
compare(img.height, 120)
compare(img.horizontalTileMode, BorderImage.Stretch)
compare(img.verticalTileMode, BorderImage.Stretch)

SignalSpy::wait() 提供了一种等待信号发出的替代方法。

另请参阅 compare() 和SignalSpy::wait()。

tryVerify(function, timeout = 5000, message = "")

如果function 在指定的timeout (以毫秒为单位)耗尽之前未计算出true ,则当前测试用例失败。该函数将被多次计算,直至达到超时。失败时将显示可选的message 。

该函数旨在测试基于异步事件而发生条件变化的应用程序。请使用verify() 来测试同步条件变化,并使用tryCompare() 来测试异步属性变化。

例如,在下面的代码中,无法使用tryCompare(),因为currentItem 属性可能会在短时间内处于null 状态:

tryCompare(listView.currentItem, "text", "Hello");

相反,我们可以使用 tryVerify() 先检查currentItem 是否不等于null ,然后再进行常规的比较:

tryVerify(function(){ return listView.currentItem })
compare(listView.currentItem.text, "Hello")

另请参阅 verify()、compare()、tryCompare() 和SignalSpy::wait()。

verify(condition, message = "")

如果 `condition ` 为 false,则使当前测试用例失败,并显示可选信息 `message`。这与 C++ 中的 `QVERIFY(condition) ` 或 `QVERIFY2(condition, message) ` 类似。

wait(ms)

在处理 Qt 事件时等待ms 毫秒。

注意:此 方法使用精确计时器进行实际等待。而您正在等待的事件可能并非如此。特别是,任何动画以及Timer QML类型都可能根据各种因素使用精确计时器或粗略计时器。 对于粗略计时器,您必须预期其与 TestCase::wait() 所使用的精确计时器相比,存在约 5% 的误差。不过,Qt 无法对该误差给出硬性保证,因为操作系统通常也不会对计时器提供硬性保证。

另请参阅 sleep()、waitForRendering() 以及Qt::TimerType 。

[since 6.5] bool waitForPolish(object windowOrItem, int timeout = 5000)

如果windowOrItem 是 Item 类型,则该函数将等待timeout 毫秒,或者直到isPolishScheduled(windowOrItem) 返回false 为止。如果isPolishScheduled(windowOrItem) 在timeout 毫秒内返回false ,则返回true ;否则返回false 。

如果windowOrItem 是窗口,则该函数会等待timeout 毫秒,或者直到isPolishScheduled() 对于该窗口管理的所有项目均返回false 为止。如果isPolishScheduled() 在timeout 毫秒内对于所有项目均返回false ,则返回true ;否则返回false 。

该方法在 Qt 6.5 中引入。

另请参阅 isPolishScheduled()、QQuickItem::polish() 和QQuickItem::updatePolish()。

waitForRendering(item, timeout = 5000)

等待timeout 毫秒,或直到渲染器渲染完item 。如果item 在timeout 毫秒内渲染完成,则返回true;否则返回false。默认的timeout 值为5000。

另请参阅 sleep() 和wait()。

warn(message)

输出message 作为警告信息。类似于 C++ 中的qWarning(message) 。

另请参阅 ignoreWarning()。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.