Java便捷API

注意:Java便捷API仅在Squish for Java版本中可用。

Java便捷函数参数

一些Java便捷函数可以接受一个modifierState参数,表示在鼠标点击时按下了哪些特殊键。有些函数还可以接受一个button参数,表示按下了哪个鼠标按钮。

modifierState的值在AWT/Swing/JavaFX和SWT中不同。修饰符状态没有枚举值,因此必须使用以下表格中与GUI工具包相关的值。

修饰符AWT/Swing/JavaFXSWT
无修饰符00
Shiftjava.awt.Event.SHIFT_MASK1org.eclipse.swt.SWT.SHIFT131072
Controljava.awt.Event.CTRL_MASK2org.eclipse.swt.SWT.CTRL262144
Metajava.awt.Event.META_MASK4
Altjava.awt.Event.ALT_MASK8org.eclipse.swt.SWT.ALT65536
Commandorg.eclipse.swt.SWT.COMMAND4194304

如果同时使用多个,它们必须进行OR操作,例如,对于Shift和Control,AWT/Swing/JavaFX使用1|2,SWT使用131072|262144

button可以是以下任何一个

按钮指定符信息
Button.NoButton通常:使目标可见并移动鼠标,但不点击。
Button.Button1左鼠标按钮
Button.Button2中鼠标按钮
Button.Button3右鼠标按钮

上面的形式适用于Python和JavaScript。对于Perl使用此:Button::Button1等。对于Ruby使用此:Button::BUTTON1等。对于Tcl使用此:enum Button Button1等。

Java便捷API成员

以下是一些快速链接到Java便捷API的成员

activateAction(objectName)

此函数将激活具有objectName符号或实际名称的JFace操作对象。

注意:此函数仅在测试Java/SWT应用程序时可用。

activateItem(objectOrName, itemText)

此函数在objectName菜单中激活指定itemText的菜单项,上下文菜单或菜单栏。

chooseColor(objectOrName, red, green, blue)

此函数隐式地调用了平台的原生“选择颜色”对话框。必须始终将objectOrName设置为应用程序的“SWT”对象(":SWT")。颜色参数必须是0到255范围内的整数。它们用于指定通过对话框选择的颜色。

注意:此函数仅在测试Java/SWT应用程序时可用。

chooseDirectory(objectOrName, path)

此函数隐式调用平台的本地“选择文件夹”对话框。objectOrName必须始终是应用程序的“SWT”对象(":SWT")或“SquishJavaFX”对象(":SquishJavaFX")。该path是一个字符串,它指定了通过对话框选择的文件夹。

注意:此函数仅在测试SWT或JavaFX应用程序时可用。

chooseFile(objectOrName, filename)

此函数隐式调用平台的本地“选择文件”对话框。objectOrName必须始终是应用程序的“SWT”对象(":SWT")或“SquishJavaFX”对象(":SquishJavaFX")。参数filename是一个字符串(可能包含路径),它指定了通过对话框选择的文件名。

注意:此函数仅在测试SWT或JavaFX应用程序时可用。

chooseFile(objectOrName, array of filenames)

可以使用filename数组指定多个文件名。

chooseFile(":SWT", ["file1", "file2"]);
chooseFile(":SWT", ["file1", "file2"]);
chooseFile(":SWT", ["file1", "file2"])
chooseFile(":SWT", ["file1", "file2"])
chooseFile(":SWT", [list "file1" "file2"])

clickButton(objectOrName)

此函数单击指定的objectOrName按钮。

clickItem(objectOrName, itemOrIndex, x, y)

clickItem(objectOrName, itemOrIndex, x, y, modifierState, button)

此函数在objectOrName视图小部件内的指定itemOrIndex上单击鼠标。此函数通常用于访问列表、表格和树等视图中的项目。对于表格,itemOrIndex是一个格式为行/列的字符串,例如:"4/21";对于其他视图,它是相关项目的文本。

单击发生在itemOrIndex项的坐标中的xy位置。参数buttonmodifierState是可选的。如果没有指定它们,则使用左鼠标按钮和空键盘修改状态进行点击。如果指定了buttonmodifierState,则使用指定的按钮和键盘修改状态进行点击。

支持的观点小部件是SWT工具包中的列表、组合和工具栏,以及AWT/Swing工具包中的JList、JTable、JTree、列表和选择。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

clickTab(objectOrName, tabText)

clickTab(objectOrName, tabText, x, y)

clickTab(objectOrName, tabText, x, y, modifierState, button)

此函数在objectOrName标签小部件上具有指定tabText的标签上单击。参数xymodifierStatebutton是可选的。如果没有提供可选参数,则使用左鼠标按钮在中点击标签,并使用空键盘修改状态。如果提供了所有参数,则此函数在objectOrName标签小部件上使用指定的button和修改器在位置xy(在objectOrName标签小部件的坐标中)上进行点击。

注意:此函数只能与org.eclipse.swt.custom.CTabFolderjavax.swing.JTabbedPane标签小部件一起使用。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

clickTreeHandle(objectOrName, itemText)

此函数在指定的 objectOrName 树小部件上点击具有指定 itemText 的展开/折叠(树柄)。支持树小部件包括 SWT 工具包的 Tree 和 AWT/Swing 工具包的 JTree。

closeMessageBox(objectOrName, result)

此函数 不可见地 执行平台的原生“消息框”关闭对话框操作。必须始终将 objectOrName 设置为应用程序的“SWT”对象 (":SWT")。result 是一个指定对话框内部按下的按钮的常量。有效的 result 值包括 SWT.ABORTSWT.CANCELSWT.IGNORESWT.NOSWT.OKSWT.RETRYSWT.YES

注意:此函数仅在测试Java/SWT应用程序时可用。

closeWindow(objectOrName)

此函数关闭 objectName 窗口(在 SWT 中为 Shell),就像使用窗口系统菜单关闭它一样。

collapse(treeItem)

如果 treeItem 是 Swing JTree 项目或 SWT Tree 项目(例如,由 Object waitForObjectItem(objectOrName, itemOrIndex) 函数返回),则将其折叠,使其子项目(如果有)不可见;否则抛出异常。(也请参阅 expand(treeItem)。)

doubleClick(objectOrName, x, y, modifierState, button)

此函数在 objectOrName 小部件上位置 xy(在 objectOrName 小部件的坐标中)处双击鼠标,使用指定的 buttonmodifierState修改状态。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

doubleClickItem(objectOrName, itemText, x, y)

doubleClickItem(objectOrName, itemText, x, y, modifierState, button)

此函数在给定 objectOrName 视图小部件内部具有指定 itemText 的项目上双击鼠标。双击操作在 xy 位置进行(在 itemText 项的坐标中)。buttonmodifierState 参数是可选的;如果没有指定,则使用左键双击并使用无键盘修改状态。如果指定了 buttonmodifierState,则使用指定的按钮和键盘修改状态进行双击。

支持的视图小部件包括 SWT 工具包中的列表、组合框和工具栏,以及 AWT/Swing 工具包中的 JList、JTable、JTree、列表和选择。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

dragAndDrop(source_­object­Or­Name, sx, sy, target_­object­Or­Name, tx, ty, operation)

dragAndDrop(source_­object­Or­Name, target_­object­Or­Name, operation)

此函数执行拖放操作。它首先在 source_objectOrName 小部件上启动拖放,起始位置在 sxsy 处(在 source_objectOrName 小部件的坐标中),然后在 target_objectOrName 小部件上执行释放,位置在 txty 处(在 target_objectOrName 小部件的坐标中)。如果省略了 sxsytxty,则取相应对象的中心位置。操作 operation 第一种是 DnD.CrossNoneDnD.CrossCopyDnD.CrossMoveDnD.CrossLinkDnD.CrossMoveTargetDnD.CrossDefault

dragItemBy(objectOrName, x, y, dx, dy, modifierState, button)

此函数执行拖放操作。它从指定位置 xy(在 objectOrName 小部件的坐标中)开始拖放指定的 objectOrName 小部件,使用指定的 button 电脑 modifierState 辅助状态。小部件将在水平方向上拖动 dx 像素,并在垂直方向上拖动 dy 像素。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

dropOn(target_objectOrName, tx, ty, operation)

dropOn(target_objectOrName, operation)

此函数执行由调用 startDrag(source_objectOrName, sx, sy) 函数启动的释放操作。它在 target_objectOrName 小部件上执行释放,位置在 txty 处(在 target_objectOrName 小部件的坐标中,如果省略了则取小部件的中心位置)。操作 operation 可以是 DnD.CrossNoneDnD.CrossCopyDnD.CrossMoveDnD.CrossLinkDnD.CrossMoveTargetDnD.CrossDefault 之一。

expand(treeItem)

如果 treeItem 是 Swing JTree 项或 SWT Tree 项(例如,由 Object waitForObjectItem(objectOrName, itemOrIndex) 函数返回),则会展开显示其子项(如果有);否则,会抛出异常。另请参阅 collapse(treeItem)

gesture(objectOrName, touches)

此函数播放手势。指定的 objectOrName 可以指任何可见的对象,仅用于同步。指定的 touches 指的是 GestureBuilder 对象,可以使用 readGesture(gesture-file) 获取。

installEventHandler(eventName, handlerFunctionNameOrReference)

此函数安装全局事件处理器。在 handlerFunctionNameOrReference 中命名的或引用的脚本函数将在发生 eventName 类型的事件时被调用。

事件名称可以是以下任意事件类型的名称

  • Crash:如果自动化测试工具(AUT)崩溃,将发生此事件。
  • DialogOpened:当打开对话框时,将发生此事件。
  • MessageBoxOpened:当打开原生 SWT 消息框时,将发生此事件。
  • 超时:当Squish响应超时时,将发生此事件。

名为 handlerFunctionName 的函数通过一个单一的参数被调用——要么是事件发生的对象,对于 MessageBoxOpened,则是消息框的文本。

注意:在Python脚本中,您可以通过传递一个实际函数或lambda函数来指定要调用的回调函数。

以SWT的 MessageBoxOpened 为例,事件处理器可能如下所示

import names
import os

def handleMessageBox(notUsedText):
    test.log("MessageBox opened: '{}' - '{}'".format(lastAlert.title, lastAlert.text))
    if lastAlert.text.startswith("Save"):
        closeMessageBox(waitForObject(names.sWT), SWT.NO)
    else:
        closeMessageBox(waitForObject(names.sWT), SWT.YES)

def main():
    fn = os.path.join(os.getenv("SQUISH_PREFIX"),
        "examples/java/addressbook_swt/AddressBookSWT.jar")
    startApplication('"{}"'.format(fn))
    installEventHandler("MessageBoxOpened", handleMessageBox)
    activateItem(waitForObjectItem(names.address_Book_Menu, "File"))
import * as names from 'names.js';

function messageBoxHandler(text) {
    test.log("MessageBox opened [" + lastAlert.title + ": " + lastAlert.text + "]")
    if (text.indexOf("Save") == 0)
        closeMessageBox(waitForObject(names.sWT), SWT.NO)
    else
        closeMessageBox(waitForObject(names.sWT), SWT.YES)
}

function main() {
    startApplication('"' + OS.getenv("SQUISH_PREFIX") +
        '/examples/java/addressbook_swt/AddressBookSWT.jar"');
    installEventHandler("MessageBoxOpened", messageBoxHandler)
    activateItem(waitForObjectItem(names.addressBookMenu, "File"));
require 'names.pl';

sub messageBoxHandler() {
    my ($text) = @_;
    test::log ("MessageBox Opened: [" . lastAlert->title() . ": " . lastAlert->text() . "]");
    if ($text =~ "^Save.*") {
        closeMessageBox(waitForObject($Names::swt), SWT->NO);
    }
    else {
        closeMessageBox(waitForObject($Names::swt), SWT->YES);
    }
}

sub main()
{
    startApplication("\"$ENV{'SQUISH_PREFIX'}/examples/java/addressbook_swt/AddressBookSWT.jar\"");
    installEventHandler("MessageBoxOpened", "messageBoxHandler");
    activateItem(waitForObjectItem($Names::address_book_menu, "File"));
require 'squish'
require 'names'

include Squish

def HandleMessageBox(text)
    Test.log("MessageBox [" + LC::LastAlert.title + ": " + LC::LastAlert.text + "]")
end

def main
    fn = File.join(ENV['SQUISH_PREFIX'], "examples/java/addressbook_swt/AddressBookSWT.jar")
    startApplication('"' + fn + '"');
    installEventHandler("MessageBoxOpened", "HandleMessageBox")
    activateItem(waitForObjectItem(Names::Address_Book_Menu, "File"))
source [findFile "scripts" "names.tcl"]

proc handleMessageBox {text} {
    test log [concat "Text: " $text]
    test log [concat "LastAlert (" [property get lastAlert title] ": " [property get lastAlert text] ")"]
}

proc main {} {
    startApplication "\"$::env(SQUISH_PREFIX)/examples/java/addressbook_swt/AddressBookSWT.jar\""
    installEventHandler "MessageBoxOpened" "handleMessageBox"
    invoke activateItem [waitForObjectItem $names::Address_Book_Menu "File"]

注意:如果要在AUT启动后执行,则 installEventHandler 函数才有效。例如,可以使用 ApplicationContext startApplication(autName) 函数。

int lastAlert.style

此属性包含最后一个被抑制的本地对话框的SWT MessageBoxDirectoryDialog 的样式。请参阅 closeMessageBox(objectOrName, result)chooseDirectory(objectOrName, path)chooseFile(objectOrName, filename)

String lastAlert.text

在SWT MessageBoxDirectoryDialog 的情况下,此属性包含消息,如果是JavaFX DirectoryChooserFileChooser 的情况,则是标题。请参阅 closeMessageBox(objectOrName, result)chooseDirectory(objectOrName, path)chooseFile(objectOrName, filename)

String lastAlert.title

此属性包含最后一个被抑制的本地对话框(SWT MessageBoxDirectoryDialog)的标题。请参阅 closeMessageBox(objectOrName, result)chooseDirectory(objectOrName, path)chooseFile(objectOrName, filename)

mouseClick(objectOrName)

mouseClick(objectOrName, x, y, modifierState, button)

此函数在指定的 objectOrName 小部件上单击鼠标。坐标 xymodifierStatebutton 都是可选的。如果没有指定它们,则在中点击小部件的中心,使用鼠标左键和空键盘修改状态。另一方面,如果给出了附加参数,则将在 xy 位置(在 objectOrName 小部件的坐标中)使用指定的 buttonmodifierState 修改状态进行点击。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

mouseClick(objectOrName, x, y, clicks, modifierState, button)

此函数在指定的 objectOrName 小部件上单击鼠标。使用指定的 buttonmodifierState 修改状态在小部件的 xy 位置(在 objectOrName 小部件的坐标中)进行点击。参数 clicks 是点击次数的计数。

注意:参数 clicks 与Java的 MouseEvent.getClickCount 函数相对应。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

mouseDrag(objectOrName, x, y, dx, dy, modifierState, button)

此函数执行鼠标拖动操作。它从指定位置开始拖动objectOrName小部件,位置为xy(在objectOrName小部件的坐标中),使用指定的buttonmodifierState修饰状态。通过dx像素水平拖动并通过dy像素垂直拖动objectOrName小部件。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

mouseWheel(n)

mouseWheel(n, modifierState)

此函数以n次数移动鼠标滚轮。当n为正时,滚轮向前旋转,当为负时,滚轮向后旋转。可选的modifierState指示在按下一个或多个修饰键的同时执行鼠标滚轮操作。

注意:mouseWheel(n)应与交互函数一起使用,以使用modifierState参数。请参阅Java便利函数参数

nativeMouseClick(objectOrName)

nativeMouseClick(objectOrName, x, y, modifierState, button)

注意:此函数针对AWT/Swing工具包。所有SWT鼠标点击都始终以本地方式执行,因此对于SWT,此函数将是多余的。

此函数在指定的 objectOrName 小部件上单击鼠标。坐标 xymodifierStatebutton 都是可选的。如果没有指定它们,则在中点击小部件的中心,使用鼠标左键和空键盘修改状态。另一方面,如果给出了附加参数,则将在 xy 位置(在 objectOrName 小部件的坐标中)使用指定的 buttonmodifierState 修改状态进行点击。

有关哪些值对于modifierStatebutton参数是有效的,请参见Java便利函数参数

readGesture(gesture-file)

此函数从测试套件目录中打开手势文件并返回一个GestureBuilder对象。然后可以将它传递给gesture(objectOrName, touches)。指定的gesture-file指的是文件名。

startDrag(source_objectOrName, sx, sy)

startDrag(source_objectOrName)

此函数在source_objectOrName小部件上启动拖动,当前位置为sxsy(在source_objectOrName小部件的坐标中;如果省略,则取小部件的中心)。可以手动执行dropOn(target_objectOrName, tx, ty, operation)函数来完成放下。

通常使用dragAndDrop(source_­object­Or­Name, sx, sy, target_­object­Or­Name, tx, ty, operation)函数在单个操作中执行拖放。然而,在有些情况下,在放下之前可能需要将鼠标移动到不同的对象上。在这些情况下,测试代码将类似于以下内容

startDrag(sourceObject, sx, sy)
mouseMove(otherObject, x, y)
dropOn(targetObject, tx, ty, operation)

type(objectOrName, text)

此函数将指定text(好像用户使用了键盘)输入到objectOrName可编辑小部件中。如果文本被尖括号(<>)包围,它被解释为一个组合键,例如"<Ctrl+Enter>"。输入区分大小写,因此type(object, "R")type(object, "r")不同。有关受支持的特殊键的列表,请参阅nativeType(keys)函数的文档。

uninstallEventHandler(eventName, handlerFunctionNameOrReference)

此函数卸载先前使用 installEventHandler(eventName, handlerFunctionNameOrReference) 安装的事件处理器。

本地Java数组

除了上述函数外,测试脚本还可以创建本地Java数组,并在数组中插入和检索存储的对象。有关使用示例,请参阅 创建和使用JavaArrays

数组 JavaArray(size)

数组 JavaArray(size, nameOfType)

这是创建本地Java数组的构造函数。size 指定它可能包含的对象数量(从0开始编号,因此最后一个有效的索引是 size - 1)。如果省略可选的 nameOfType 字符串,则函数将返回类型为 java.lang.Object[size] 的数组;否则数组的类型将是 nameOfType[size]

nameOfType 是一个字符串,可以指定非对象类型,如 "int",或对象类型,如 "java.lang.String"

JavaArray 有两个函数和一个属性。

Object JavaArray.at(index)

此函数返回数组中位置为 index 的对象。如果 index 超出范围,则会引发可捕获的异常。

int javaArray.length

这个只读属性包含数组中的位置数。第一个项目位于位置 0,最后一个项目位于位置 javaArray.length - 1

Object JavaArray.set(index, object)

此函数将数组中位置为 index 的项目设置为给定的 object。如果 index 超出范围或 object 是无效类型(例如,当一个JavaArray包含整数时为字符串),则会引发可捕获的异常。

GestureBuilder

此类对象包含重放 gesture(objectOrName, touches) 所需的触摸手势信息。通过 readGesture(gesture-file) 返回此类的一个实例。触摸笔迹由JavaFX 场景 坐标点定义。

有关如何使用 GestureBuilder 对象操作手势信息的示例,请参阅 如何使用GestureBuilder类

int GestureBuilder.areaWidth

此手势定义的区域宽度。这将是 场景 宽度。

int GestureBuilder.areaHeight

此手势定义的区域高度。这将是 场景 高度。

GestureBuilder 列表中在 手势创建手势操作 部分中列出的所有方法,除非明确指定,否则都返回 GestureBuilder 对象。

手势创建

本节列出了手动创建 GestureBuilder 对象的方法。

GestureBuilder(width, height, unit)

GestureBuilder(xml)

用于创建GestureBuilder对象的两个构造函数。参数widthheight是目标场景大小。参数unit可以是0或1,分别代表像素或毫米。也可以使用GestureBuilder.PixelGestureBuilder.MilliMeter常量。

第二个构造函数通过传递一个包含XML的字符串来构建GestureBuilder对象,该XML的结构应与记录的手势文件相同。

Object GestureBuilder.addStroke(x, y)

Object GestureBuilder.addStroke(startTime, x, y)

开始新的绘制。从一个手指或笔从触摸屏幕到释放屏幕的整个移动称为一个绘制。触摸坐标是(x, y)。

对于非第一笔绘制,可以使用startTime参数指定时间偏移量(以毫秒为单位)。绘制不能在时间上断裂,整个手势过程中至少要有一个手指或笔处于按下状态。最大同时触摸数依赖于设备。

Object GestureBuilder.curveTo(duration, controlX, controlY, endX, endy)

Object GestureBuilder.curveTo(duration, control1X, control1Y, control2X, control2Y, endX, endy)

向最后添加的绘制添加一个贝塞尔曲线移动,持续时间为duration毫秒。曲线从最后添加的移动的终点坐标开始或如果没有添加到绘制中,则从绘制接触坐标开始。终点坐标使用endXendY指定。可以使用一个或两个所谓的控制点。

Object GestureBuilder.lineTo(duration, endX, endy)

向最后添加的绘制添加一个线条移动,持续时间为duration毫秒。线条从最后添加的移动的终点坐标开始或如果没有添加到绘制中,则从绘制接触坐标开始。终点坐标使用endXendY指定。

Object GestureBuilder.build()

从添加的绘制和动作创建手势。调用此方法后,无法再添加绘制或动作。

Gesture manipulation

Object GestureBuilder.accelerate(factor)

根据一个系数改变绘制速度。系数在0.0到1.0之间会减慢手势速度,大于1.0则会加快。

Object GestureBuilder.rotate(degrees)

Object GestureBuilder.rotate(degrees, originX, originY)

旋转绘制。参数degrees是以逆时针方向为角度的度数。参数originXoriginY定义了旋转操作的起点。如果省略,则取区域中心作为起点。

Object GestureBuilder.scale(scale)

Object GestureBuilder.scale(scaleX, scaleY)

Object GestureBuilder.scale(scaleX, scaleY, originX, originY)

改变笔画的尺寸。水平方向的缩放因子为scaleX,垂直方向为scaleYoriginXoriginY定义了缩放操作的原点。如果省略,则取区域中心作为原点。当也省略scaleY时,则在两个方向上的缩放是均匀的。

Object GestureBuilder.translate(x, y)

移动笔画。xy指定了移动。对于x的正值将笔画向右移动,对于y的正值将笔画向下移动。

Java硬编码合成属性

除了公共Java类字段和从get*is*函数生成的合成属性外,Squish还提供了一些额外的属性,以便更容易识别对象。(有关更多详细信息,请参阅定义属性集

这些属性只能与对象名称一起使用,并且在对象属性列表中不可见。

属性类型描述
aboveWidget对象保留此小部件在上一个逻辑父容器复合中的对象。这应该用于没有标题但经常带有附加小部件的对象。例如,编辑框没有标题,但可能会有一个标签在上面。
arrowDirection字符串保留启用箭头样式的SWT按钮的方向。
buttonType字符串保留SWT按钮的类型。此属性对于识别带有箭头的按钮很有用。
caption字符串保留对象的标题、标题或文本,如果此对象通常具有要显示的此类文本。
container对象保留包含此对象的父容器复合。这些通常是标签页或菜单栏。
firstItemText字符串保留为子SWT ToolItem对象找到的第一个文本。如果没有找到文本,则使用工具提示文本。如果没有找到文本且未设置工具提示文本,则此属性值可能为空字符串。
firstTabCaption字符串保留CTabFolder的第一个CTabItem的标题。如果没有找到文本,则此属性值可能为空字符串。
leftWidget对象保留在此小部件的同一逻辑父容器复合中位于左侧的对象。这应该用于没有标题但经常带有附加小部件的对象。例如,编辑框没有标题,但通常在其左侧有一个标签。
menuStyle字符串保留SWT菜单的样式——这表示菜单是菜单栏、弹出菜单还是下拉菜单。
type字符串保留对象的类名——但名称中的任何点用下划线替换。
window对象保留包含此对象的最顶层窗口。

Java自定义小部件扩展API

简介

Squish可以与所有标准AWT/SWT小部件无缝协作。然而,一些自定义小部件可能以非标准方式表示其子组件,即不是作为AWT/SWT组件。例如,画布可能使用普通的Java对象来表示显示的项目。或者一个甘特图组件可能渲染其自己的内容,从模型中获取数据。Squish的Java扩展API使得扩展Squish成为可能,以便AWT和SWT应用程序中的非标准组件可以公开它们的API,使它们被Squish访问,并在测试脚本中像任何其他组件一样访问。

为了告诉Squish要公开哪些功能,我们引入了可检查类(Inspectable)的概念。可检查类可以响应当前Squish对特定类型对象的查询。例如,可检查类可以处理画布项目类型,并提供API供Squish获取画布的界限或其父组件,或者返回所有子项目。具体的API列表请参阅可检查接口(Inspectable interface);请参阅Java扩展API参考

一旦可检查类注册,每当Squish遇到一个对象时,Squish就会查询每一个可检查类,看它是否可以处理该对象(即对象的类型)。如果其中一个可检查类报告它识别对象的类型作为它可以处理的类型,Squish就会使用该可检查类的接口与该对象交互。这使得Squish可以像它与标准AWT/SWT类型(它自带提供支持的小部件)一样处理对象——例如,Squish可以查询可检查类以查看对象是否已收到鼠标点击。

所有您想让Squish能够处理类型的可检查类都应该放置在一个“包装器”(wrapper)库中。一个干净的方法是把所有的可检查类都放在他们自己的jar中,尽管也可以将它们添加到现有应用程序的jar中。canvastest示例显示了如何将可检查类放入自己的jar中。

使用Java扩展API和适当的包装器,可以与非AWT/SWT组件一起支持标准的AWT/SWT组件,这样Squish就可以

  • 在测试脚本中识别AWT/SWT和非AWT/SWT组件。
  • 在AWT/SWT和非AWT/SWT组件上使用验证点。
  • 在整体的Spy层次结构中显示AWT/SWT和非AWT/SWT组件。
  • 使用对象选择器选择AWT/SWT和非AWT/SWT组件。

另请参阅包装自定义类

自定义画布示例

为了说明如何使用包装器扩展现有的AWT应用程序,我们将使用与Squish for Java一起提供的canvastest示例。您可以在SQUISHDIR/examples/java/canvastest中找到源代码。(我们也可以使用完全相同的方法扩展SWT应用程序。)

应用程序的源文件包括CanvasTest.javaMyCanvas.javaMyCanvasItem.javaMyCanvasGroup.javaMyCanvasShape.javaMyRectCanvasItem.javaMyCircleCanvasItem.java,共同构成了一个提供简单画布和多个物品的AWT应用程序。

我们希望测试脚本能够测试 canvastest 应用程序,以便能够查询应用程序的 MyCanvas 对象——检索一个 MyCanvas,获取一个 MyCanvas 的父对象,获取画布的边框矩形,以及获取特定位置的 MyCanvasItem 项目,或者获取画布的所有 MyCanvasItem 项目。此外,我们希望能够查询 MyCanvasItem 对象,获取它们的边框矩形等。要做到所有这些,我们必须创建合适的 Inspectable Java 类,Squish 可以查询这些类以获取接口,它可以通过这些接口查询应用程序的画布和画布项,就像它们是标准的 AWT/SWT 对象一样。

我们将 Inspectable 类放在与应用程序其他 Java 文件相同的目录下 MyCanvasFactory.java 文件中。Squish 的 Java 扩展 API 类包含在文件 SQUISHDIR/lib/squishjava.jar 中,因此此文件必须包含在类路径中才能编译 MyCanvasFactory.java

有关扩展 API 信息,请参阅 Java 扩展 API 参考

创建完 Inspectable 类之后,Squish 必须知道它们存在,以便它可以使用它们。为此只需告诉 Squish 哪个应用程序使用包装器以及包装器位于何处。这通过在 squishserver 上设置配置来完成。

squishserver --config setConfig CanvasTest.jar \
$SQUISHDIR/examples/canvastest/Extension.ini

在这里,我们使用 Unix 风格的路径,并假设环境变量 SQUISHDIR 包含 Squish 的安装目录。使用的路径实际上是什么并不重要(只要是一个绝对路径,并且是正确的 Extension.ini 文件路径)。

Extension.ini 文件必须列出扩展所在的目录。一个相对路径是可能的,且应相对于应用程序的工作目录。以下是 canvastest 的 Extension.ini 文件的内部内容

[general]
JavaExtensionDir="."

如果你使用 Windows,可以要么使用正斜杠,要么通过将目录写入 ini 文件来转义反斜杠。

为了演示使用包装器测试 AUT,我们在 SQUISHDIR/examples/java/suite_canvastest_js 中提供了一个非常基本的测试套件。

有时提供的应用程序对象不合适,因为它们不提供父子关系。在这种情况下,可以使用辅助类。必须将此类添加到 extension.jar。

例如,考虑一个流行组件,它画了五个星星,颜色表示百分比。在这种情况下,有一个辅助类,它用组件和索引表示一个星星。组件的子代是五个此类实例。对于每个实例,组件是其父对象。

因此,当在星星处时,为组件创建的 Inspectable 在 getChildren 和 getChildAt 时创建辅助对象。额外的 Inspectable 对于辅助对象使其对 Squish 可见。为任何可能需要的属性添加公共 getter 函数,例如 getIndex 和 getFill。

确保辅助类重写了 java Object 的 equals 和 hashCode 方法,以至于当字段相等时 equals 返回 true,而 hashCode 是一个区分等价性的值。在上面的例子中,需要以下代码

public boolean equals(Object obj) {
    if ( obj == null || !( obj instanceof StarHelper))
        return false;
    StarHelper other = (StarHelper)obj;
    return other.index == index && other.component.equals( component);
}
public int hashCode() {
    return component.hashCode() + index + /*some random number*/ 43;
}
创建 .jar 文件

表示信息文件必须包含一个 Extension 条目,其值具有 public static void init(InspectableRegistry registry) 方法的类。此函数是扩展的入口点,并应在 registry 中注册工厂类。

对于使用与系统类加载器不同的一个或多个类加载器来加载类中的应用程序,必须添加一个名为 LoadAtClass 的条目。所有的 RCP 都属于这一类别。

此条目的值是触发扩展注册的类,一旦该类被类加载器加载。这可能需要反复尝试,因为所有被注册的工厂类的字段都必须已由类加载器所知晓。

在此示例中,LoadAtClass 被设置为 Canvas 类。这里是指扩展 jar 的清单文件。

Extension: MyCanvasFactory
LoadAtClass: MyCanvas

Java 扩展 API 参考

颜色

类 Color

可检测

接口 Inspectable —— 在 Squish 中实现自定义 Java 支持时需要实现此接口。

InspectableAdapter

类 InspectableAdapter —— 用于编写扩展的适配器类。

InspectableFactory

接口 InspectableFactory —— 一个工厂,为它管理的自定义对象提供 Inspectable。

InspectableRegistry

类 InspectableRegistry —— 此类允许注册实现 Inspectable 的扩展的工厂。

ItemExtension

接口 ItemExtension —— 当可检测的对象处理具有文本项的对象时(在测试脚本中使用 waitForObjectItem 编写),必须实现此接口。

ObjectQuery

接口 ObjectQuery

类 Point —— 不可知的工具点类。

矩形

类 Rect —— 不可知的方形类。

TableExtension

接口 TableExtension —— 可以实现此接口的 Inspectable,其中其可检测的对象有行和列。

TargetExtension

接口 TargetExtension —— 当可检测的对象是另一个对象的一部分时可以实施此接口。

ViewportExtension

接口 ViewportExtension —— 当可检测的对象具有滚动能力时可以实施此接口。

©2024 测试软件公司。此处包含的文档贡献是各自所有者的版权。
此处提供的文档根据 GNU 自由文档许可证版本 1.3 的条款授权,由自由软件基金组织发布。
Qt 以及相应的标志是芬兰和/或其他国家/地区的 Qt 公司的商标。其他所有商标均为各自所有者的财产。