TestCase QML Type

代表单元测试案例。更多

Import Statement: import QtTest
Inherits:

Item

属性

方法

详细说明

QML 测试用例介绍

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

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 类型。所有测试完成后,测试程序将退出。如果测试用例不需要运行(因为前提条件失败),则可将optional 设为 true。

数据驱动测试

可以使用以"_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 基准框架运行多次,并报告运行的平均时序值。这相当于在 C++ 版本的 QTestLib 中使用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 字符(长度为一的字符串)。

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)

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

管理动态创建的测试对象

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.
    }
}

对于通过ComponentcreateObject() 函数创建的对象,可以使用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
}

另请参阅 SignalSpyQt Quick Test.

属性文档

completed : bool

一旦测试用例执行完毕,该属性将被设置为 true。测试用例只执行一次。初始值为 false。

另请参阅 runningwhen


name : string

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

TestCase {
    name: "ButtonTests"
    ...
}

optional : bool

测试程序中可提供多个TestCase 类型。当所有类型都完成后,应用程序将退出。如果测试用例不需要运行(因为先决条件失败),则可将此属性设为 true。默认值为 false。

TestCase {
    when: false
    optional: true
    function test_not_run() {
        verify(false)
    }
}

另请参阅 whencompleted


running : bool

当测试用例运行时,该属性将被设置为 true。初始值为 false,一旦测试用例完成,该值将再次变为 false。

另请参阅 completedwhen


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 类型都已触发并运行,测试应用程序将退出。optional 属性可用于排除TestCase 类型。

另请参阅 optionalcompleted


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 = "")

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

另请参阅 tryCompare() 和fuzzyCompare


object createTemporaryObject(Component component, object parent, object properties)

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

如果在创建对象时出现错误,null

此函数内部调用component.createObject() 。

另请参阅 Managing Dynamically Created Test Objects


object createTemporaryQmlObject(string qml, object 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 对象,但它不会被解释为正则表达式;相反,正则表达式将被传递到QRegularExpression

注意: ignoreMessage() 优先于此函数,因此任何与ignoreMessage()failOnWarning() 的模式匹配的警告都将被忽略。

此方法在 Qt 6.3 中引入。

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


QtObject findChild(parent, objectName)

通过objectName 返回parent 的第一个子项,如果不存在该子项,则返回null 。可视和非可视子代都是递归搜索,可视子代优先。

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

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

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

如果actualexpected 的值都能转换成颜色值,该函数也可用于颜色比较。如果 RGBA 通道值的任何差值大于delta ,则测试失败。

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


object grabImage(item)

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

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

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

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

  • red(x, y) 返回xy位置处像素的红色通道值
  • green(x, y) 返回xy位置像素的绿色通道值
  • blue(x, y) 返回xy位置处像素的蓝通道值
  • alpha(x, y) 返回x,y位置处像素的阿尔法通道值
  • pixel(x, y) 返回x,y位置处像素的颜色值
  • equals(image) 如果此图像与图像相同,则返回 - 参见 (自 5.6 起)true QImage::operator==

    例如

    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 中为属性赋值时,因赋值而必须对项进行的布局可能不会立即生效,而会推迟到项被打磨后才生效。在这种情况下,您可以使用此函数来确保在继续执行测试之前,项目已被完善。例如

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 毫秒。

事件将发送到TestCase 窗口,如果有多个窗口,则发送到当前活动窗口。详情请参见QGuiApplication::focusWindow() 。

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


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

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

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

注意:在某些情况下,应使用keyRelease() 释放按键。

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


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

模拟在当前聚焦项目上释放key ,可选modifiers 。如果delay 大于 0,测试将等待delay 毫秒。

事件将发送到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 )。点击的位置由xy 定义。如果xy 未定义,位置将是item 的中心。如果指定了delay ,测试将在按下和松开按钮前等待指定的毫秒数。

xy 提供的位置将从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 )所产生的全部事件序列。

该方法再现了用户双击鼠标时产生的一系列鼠标事件:按下-释放-按下-双击-释放。

点击的位置由xy 定义。如果没有定义xy ,位置将是item 的中心。如果指定了delay ,测试将在按下和释放按钮前等待指定的毫秒数。

xy 提供的位置将从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)

在按下button 和可选的modifiers 的情况下,模拟在item 上拖动鼠标。初始拖动位置由xy 定义,拖动距离由dxdy 定义。如果指定了delay ,测试将等待指定的毫秒数后才释放按钮。

xy 提供的位置将从item 的坐标系转换为窗口坐标系,然后传送。如果item 被其他项目遮挡,或者item 的子项占据了该位置,那么事件将被传递到其他项目。

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


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

将鼠标指针移动到itemxy 给定的位置,同时保持buttons (如果给定)。自 Qt XML 6.0 起,如果未定义xy ,则位置将是item 的中心。

如果给出delay (毫秒),测试将在移动鼠标指针前等待。

xy 所给出的位置将从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 )。位置由xy 定义。如果xy 未定义,位置将是item 的中心点。如果指定了delay ,测试将在按下鼠标前等待指定的毫秒数。

xy 提供的位置将从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 )。释放的位置由xy 定义。如果xy 未定义,位置将是item 的中心。如果指定了delay ,测试将等待指定的毫秒数后才释放按钮。

xy 提供的位置将从item 的坐标系转换为窗口坐标系,然后传送。如果item 被其他项目遮挡,或者item 的子项占据了该位置,那么事件将被传递到其他项目。

另请参阅 mousePress(),mouseClick(),mouseDoubleClickSequence(),mouseMove(),mouseDrag() 和mouseWheel().


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

在按下button 和可选modifiers 的情况下,模拟在item 上旋转鼠标滚轮。滚轮事件的位置由xy 定义。如果指定了delay ,测试将等待指定的毫秒数后才释放按钮。

xy 提供的位置将从item 的坐标系转换为窗口坐标系,然后传送。如果item 被其他项目遮挡,或者item 的子项目占据了该位置,那么事件将被发送到其他项目。

xDeltayDelta 包含以八分之一度为单位的车轮旋转距离。更多详情,请参阅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 上指定的propertyexpected 不一致,则当前测试用例失败,并显示可选的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 XML 事件时等待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 被呈现器呈现。如果itemtimeout 毫秒内渲染完毕,则返回 true,否则返回 false。timeout 的默认值为 5000。

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


warn(message)

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

另请参阅 ignoreWarning()。


© 2025 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.