如何使用事件处理程序

在Squish测试脚本中,可以响应在AUT(自动化测试对象)内部发生的事件。这非常有用,比如可以提供一个当对话框意外出现时的测试脚本响应,例如错误消息框。这可以通过为特定事件注册一个事件处理函数来完成,当该事件在指定的对象上发生时,或在该对象类型的对象上发生时,或对任何对象发生时,都应该调用该函数。

通过调用一个installEventHandler(eventName, handlerFunctionName)函数来注册事件处理函数。对于应适用于所有AUT对象的处理函数——也就是说,是全局事件处理函数——只需传递事件类型和处理函数作为参数。对于应适用于特定对象或特定类型所有对象的处理函数,首先传递对象或类型,然后是事件类型和处理函数。除了标准工具包事件(如Qt的QKeyEvent)之外,还支持某些Squish和工具包特定的通用事件,例如MessageBoxOpenedCrash

注意:对于Squish for Web,事件处理函数总是不带有任何参数被调用,而不是传递一个对象(通常是事件发生的对象)。虽然仍然可以在Squish for Web事件处理函数中访问对象,但必须我们自己获取对象的引用。例如,使用Object waitForObject(objectOrName)函数。

在以下小节中,我们将查看所有三种情况的示例事件处理函数。

全局事件处理函数

当消息框弹出时,将发生MessageBoxOpened事件。(事实上,MessageBoxOpened事件仅适用于Squish for Java、Squish for Qt和Squish for Windows版本;然而,其他工具包也有类似的事件。)像所有这样的事件一样,测试脚本将忽略事件,但我们可以在每次发生此类事件时注册一个事件处理函数。将这样的全局事件与特定对象或类型相关联实际上没有意义,因此通常由全局事件处理函数处理。

在这里,我们将查看创建和安装消息框处理器的示例。

def handleMessageBox(messageBox):
    test.log("MessageBox opened: '%s' - '%s'" % (
        messageBox.windowText, messageBox.text))
    messageBox.close()

def main():
    startApplication("myapp")
    installEventHandler("MessageBoxOpened", "handleMessageBox")
    ...
function handleMessageBox(messageBox)
{
    test.log("MessageBox opened: '" + messageBox.windowText +
        "' - '" + messageBox.text + "'");
    messageBox.close();
}

function main()
{
    startApplication("myapp");
    installEventHandler("MessageBoxOpened", "handleMessageBox");
    // ...
}
sub handleMessageBox
{
    my $messageBox = shift @_;
    test::log("MessageBox opened: '" . $messageBox->windowText .
        "' - '" . $messageBox->text + "'");
    $messageBox->close();
}

sub main
{
    startApplication("myapp");
    installEventHandler("MessageBoxOpened", "handleMessageBox");
    # ...
}
# encoding: UTF-8
require 'squish'
include Squish

def HandleMessageBox(messageBox)
    Test.log("MessageBox opened: '%s' - '%s'" % [
        messageBox.windowText, messageBox.text])
    messageBox.close
end

def main
    startApplication("myapp")
    installEventHandler("MessageBoxOpened", "HandleMessageBox")
    ...
end
proc handleMessageBox {messageBox} {
    test log [concat "MessageBox opened: '" \
        [property get $messageBox windowText] "' - '" \
        [property get $messageBox text]  "'"]
    invoke $messageBox close
}

proc main {} {
    invoke startApplication "myapp"
    installEventHandler "MessageBoxOpened" "handleMessageBox"
    # ...
}

注意,如果我们使用类似Squish for Web的事件(例如,ModalDialogOpened),对话框将不会被作为参数传递,因为Squish for Web事件处理函数不接收任何参数。

另一种特别的事件是Crash。当我们想要安装一个在AUT崩溃时被调用的处理函数时,这非常有用——例如,进行清理或重启AUT。(Crash事件由所有Squish版本支持,除了Squish for Web。)以下是一个示例

def crashHandler():
    test.log("Deleting lock files after AUT crash")
    deleteLockFiles()

def main():
    startApplication("myapp")
    installEventHandler("Crash", "crashHandler")
    ...
function crashHandler()
{
    test.log("Deleting lock files after AUT crash");
    deleteLockFiles();
}

function main()
{
    startApplication("myapp");
    installEventHandler("Crash", "crashHandler");
    // ...
}
sub crashHandler
{
    test::log("Deleting lock files after AUT crash");
    deleteLockFiles();
}

sub main
{
    startApplication("myapp");
    installEventHandler("Crash", "crashHandler");
    # ...
}
# encoding: UTF-8
require 'squish'
include Squish

def crashHandler
    Test.log("Deleting lock files after AUT crash")
    deleteLockFiles
end

def main
    startApplication("myapp")
    installEventHandler("Crash", "crashHandler")
    ...
end
proc crashHandler {} {
    test log "Deleting lock files after AUT crash"
    deleteLockFiles
}

proc main {} {
    invoke startApplication "myapp"
    installEventHandler "Crash" "crashHandler"
    # ...
}

第三种特别事件是Timeout事件。这些事件在AUT无法在五分钟内对某些Squish命令做出响应时触发。这可能发生在应用程序陷入无限循环的情况下,或者由于其他原因导致它无法做出响应。你可以安装一个事件处理函数来处理此类情况,以便测试能够优雅地处理这些情况。超时时间可以通过使用squishrunner的或squishserver的setResponseTimeout选项(参见配置squishrunner配置squishserver),或者使用squishide(参见Squish首选项子窗格)来更改。

特定类型所有对象的事件处理函数

可以为指定类型的所有对象设置一个事件处理程序,使其响应特定的某些类型的事件。当前只有Qt版本支持这种用法,具体使用installEventHandler(eventName, handlerFunctionName)函数。例如,我们可以安装一个事件处理程序,每当在QCheckBox上发生QMouseEvent时,这个事件处理程序就会被调用。这意味着每次事件发生时,即是每当AUT的任何复选框被点击时,事件处理程序就会被调用。下面是一个示例。

def handleCheckBox(obj):
    test.log("QCheckBox '%s' clicked" % objectName(obj))

def main():
    startApplication("myapp")
    installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox")
    ...
function handleCheckBox(obj) {
    test.log("QCheckBox '" + objectName(obj) + "' clicked");
}

function main() {
    startApplication("myapp");
    installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox");
    // ...
}
sub handleCheckBox
{
    my $obj = shift @_;
    test::log("QCheckBox '" . objectName($obj) . "' clicked");
}

sub main
{
    startApplication("myapp");
    installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox");
    # ...
}
# encoding: UTF-8
require 'squish'
include Squish

def handleCheckBox(obj)
    Test.log("QCheckBox '%s' clicked" % [objectName(obj)])
end

def main
    startApplication("myapp")
    installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox")
    ...
end
proc handleCheckBox {obj} {
    test log [concat "QCheckBox '" [objectName $obj] "' clicked"]
}

proc main {} {
    invoke startApplication "myapp"
    installEventHandler "QCheckBox" "QMouseEvent" "handleCheckBox"
    # ...
}

特定对象的事件处理程序

Squish支持的第三种事件处理类型是针对特定对象的。当前只有Qt工具包支持该功能。我们可以安装一个事件处理程序,每当行编辑器接收到QKeyEvent时会被调用,因此每当将文本输入到行编辑器中时,事件处理程序就会被调用。下面是一个示例。

def handleDescriptionLineEdit(obj):
    lineEdit = cast(obj, QLineEdit)
    test.log("QLineEdit '%s' text changed: %s" % (
        objectName(obj), lineEdit.text))

def main():
    startApplication("myapp")
    lineEdit = waitForObject(":Description:_QLineEdit")
    installEventHandler(lineEdit, "QKeyEvent",
        "handleDescriptionLineEdit")
    ...
function handleDescriptionLineEdit(obj)
{
    var lineEdit = cast(obj, QLineEdit);
    test.log("QLineEdit '" + objectName(obj) +
        "' text changed: " + lineEdit.text)
}

function main()
{
    startApplication("myapp");
    var lineEdit = waitForObject(":Description:_QLineEdit");
    installEventHandler(lineEdit, "QKeyEvent",
        "handleDescriptionLineEdit");
    // ...
}
sub handleDescriptionLineEdit
{
    my $obj = shift @_;
    my $lineEdit = cast($obj, QLineEdit);
    test::log("QLineEdit '" . objectName($obj) .
        "' text changed: " . $lineEdit->text);
}

sub main
{
    startApplication("myapp");
    my $lineEdit = waitForObject(":Description:_QLineEdit");
    installEventHandler($lineEdit, "QKeyEvent",
        "handleDescriptionLineEdit");
    # ...
}
# encoding: UTF-8
require 'squish'
include Squish

def handleDescriptionLineEdit(obj)
    lineEdit = cast(obj, QLineEdit)
    Test.log("QLineEdit '%s' text changed: %s" % [
        objectName(obj), lineEdit.text])
end

def main
    startApplication("myapp")
    lineEdit = waitForObject(":Description:_QLineEdit")
    installEventHandler(lineEdit, "QKeyEvent",
        "handleDescriptionLineEdit")
    ...
end
proc handleDescriptionLineEdit {obj} {
    set lineEdit [cast $obj QLineEdit]
    test log [concat "QLineEdit '" [objectName $obj] \
        "' text changed: " [toString [property get $lineEdit text]]]
}

proc main {} {
    invoke startApplication "myapp"
    set lineEdit [waitForObject ":Description:_QLineEdit"]
    installEventHandler $lineEdit "QKeyEvent" "handleDescriptionLineEdit"
    # ...
}

作为obj传递的对象只是一个通用的Squish对象;我们必须使用Object cast(object, type)函数将其转换为我们想访问其方法和属性的特定类型的对象。

©2024 The Qt Company Ltd. 本文件中的文档贡献版权为各自所有者。
本文件提供的文档根据自由软件基金会发布的《GNU自由文档许可证》的条款许可,版本为1.3。
Qt及其相应标志是The Qt Company Ltd.在芬兰和其他国家/地区的商标。所有其他商标均为其各自所有者的财产。