改进对象识别

当Squish记录测试时,它通过对象属性来识别大多数对象。对于Squish识别的每个对象,它都在对象映射中创建一个条目。每个条目是一对名称——一个符号名(变量名)和一个实际名(属性名-值的映射)。在测试运行时,Squish会使用多属性实际名的值作为在AUT内存中查找对象的查找条件。

属性可以是数字、字符串或对象。对于具有对象值的属性(即值是另一个对象的名称,例如容器和窗口属性),将使用Squish的对象查找功能进行另一次搜索。

对象属性只能完全匹配,而大多数字符串属性可以使用精确匹配、通配符或正则表达式匹配。一些特殊属性也需要精确匹配,例如类型、tagName(在Squish for Web中)和basetype(在Squish for Java中)。

注意:在Squish for Web中,className属性不同寻常,因为其值是字符串列表(类名),如果使用精确匹配,只要任何元素的类属性的类与指定的匹配,匹配即可成功。

匹配具有可变文本的对象

一个常见问题是许多应用程序会改变某些小部件使用的文本。例如,一个按钮的文本可能从暂停变为继续然后再变回,或者应用程序可能将当前文件的名称或工作区的名称放在主窗口标题栏的标题中。例如,假设我们有以下一个虚构的MainWindow对象的实际名称,该对象的标题为"AddressBook v1.3 - google contacts.dat"

{'windowTitle': 'AddressBook v1.3 - google contacts.dat', 'type':'MainWindow'}

这个多属性名称将与应用程序中类型为MainWindow且标题与上面显示相匹配的第一个对象匹配。

这种名称在大多数情况下工作得很好,并且当记录测试时将自动生成(有关更多信息,请参阅对象名称生成)。不幸的是,由于窗口标题发生变化,这可能会破坏指向它或其子对象的类名。

如果我们想使MainWindow的实际名称更通用,我们可以删除该属性,或使用通配符或正则表达式匹配选项。在对象映射编辑器中,可以通过双击实际名中属性与值之间的等于运算符选择一个,如图所示

{}

更改实际名属性中的匹配运算符。

我们可以通过查看脚本对象映射的suite_xyz/shared/scripts/names.(py|pl|rb|tcl|js)文件来了解这些对象名称的表示方法,如图所示

MainWindow_Wildcard = {"type": "MainWindow", "windowTitle": Wildcard("Address Book*")}
MainWindow_Regex =    {"type": "MainWindow", "windowTitle": RegularExpression("Address Book.*")}
export var mainWindowWildcard = {"type": "MainWindow", "windowTitle": new Wildcard("Address Book*")};
export var mainWindowRegex =    {"type": "MainWindow", "windowTitle": new RegularExpression("Address Book.*")};
our $mainwindow_wildcard = {"type" => "MainWindow", "windowTitle" => wildcard("Address Book*")};
our $mainwindow_regex =    {"type" => "MainWindow", "windowTitle" => regularExpression("Address Book.*")};
MainWindow_Wildcard = {:type => "MainWindow", :windowTitle => Wildcard.new("Address Book*")}
MainWindow_Regex =    {:type => "MainWindow", :windowTitle => RegularExpression.new("Address Book.*")}
set MainWindow_Wildcard [::Squish::ObjectName type MainWindow windowTitle {-wildcard {Address Book*}}]
set MainWindow_Regex    [::Squish::ObjectName type MainWindow windowTitle {-regularexpression {Address Book.*}}]

在实际情况下,您不需要这两个条目;它们是等效的。两个实际名称都指定窗口标题必须以"Address Book"开头,后跟零个或多个其他字符。

通配符版本使用*作为通配符,代表零个或多个任意字符。正则表达式版本使用点(。)匹配单个字符,星号(*)作为量词修改元字符,应用于它前面的内容,使其"零个或多个"。这两个都应该匹配"AddressBook - Untitled"和"AddressBook - MyAddresses.adr"。

精确匹配

这种匹配可以在所有情况下使用,并且是类型和值是对象(即使用实际名指定的对象)的唯一允许匹配类型。以下是一个示例

{"type": "LineEdit", "visible": 1, "buddy": {"text": "Phone:", "type": "QLabel"}}

该真实名称用于标识一个类型为LineEdit的对象,该对象的可视设置为true(1),并且有一个关联的标签——伙伴,标签的指定则使用另一个真实名称。

通配符匹配

通配符语法用于模糊匹配。这种匹配不能用于类型属性或符号对象名称。

当使用通配符匹配时,?*[]\字符都具有特殊含义,且不会被直接匹配。所有其他字符都被直接匹配。

?此字符代表任意一个单字符,无论是什么字符
*此字符代表任意数量的任意字符——包括没有字符
?*这两个字符一起代表至少任意一个字符(即,任意一个单字符后跟零个或多个任意字符)
[...]方括号用于指定一组一或多个字符,其中至少必须匹配任何一个。例如,[0-9]恰好匹配一个数字,而[aAbBcC]仅匹配“a”、“b”或“c”,不论是大小写
\反斜杠用于转义一个特殊字符,因此\?代表一个实际的"?",而\*代表一个实际的"*"。不幸的是,方括号不能转义,因此总是保留它们的特殊含义,所以匹配实际方括号的唯一方法是使用?(它将匹配任何内容),或者使用正则表达式语法

这里有一个包含通配符的真实名称

{'type' : 'LineEdit', 'visible':'1',
 'buddy': {'type':'Label', 'text':Wildcard("Name*\?"} }

这个真实名称用于标识一个类型为LineEdit的对象,该对象的可见属性设置为true(1),并且有一个关联的标签——伙伴,伙伴的指定使用另一个真实名称。但在这里,伙伴的标签文本使用通配符匹配,并且必须包含文本"Name"后面跟零个或多个其他字符,然后是一个文字的"?"。

这里有一个包含正则表达式属性匹配的真实名称

{'caption': RegularExpression('UsefulApp v[1-9].[0-9] - ?*.[dD][aA][tT]'),
 'type': 'MainWindow'}

在这里,标题必须具有以文字"text "UsefulApp v"开始,后面跟一个数字(不包括零),然后是一个点,然后是另一个数字,然后是一个空格、一个连字符和一个空格,然后至少一个字符(用?表示),然后是零个或多个其他字符(由于*),最后是".dat"(大写或小写)。注意,如果我们指定标题的文件名部分为*.[dD][aA][tT],它将匹配后缀本身,即".dat",因为*符号可以匹配零个字符。通过从?开始,我们确保在后缀之前至少匹配一个字符。

正则表达式匹配

正则表达式语法用于模糊匹配。这种匹配不能用于类型或者用于值是对象的属性(即,使用另一个真实或符号名称指定)。正则表达式匹配允许我们编写更复杂的——可能更难以理解和维护——匹配表达式,这比使用通配符语法所能达到的要复杂。因此,我们建议尽可能使用通配符匹配,因为它阅读和编写都更容易。

注意: 在Squish for Web版本中,正则表达式语法与JavaScript支持的正则表达式语法相同。关于这种语法的文档可在Regular-Expressions.infow3schools.com找到。对于所有其他Squish版本,使用Qt QRegExp语法—这在此处有记录:QRegExp

真实(多属性)名称属性

哪些属性可以用于标识一个特定的对象?答案并不简单,因为这些属性是动态发现的。

以Qt工具包为例:Squish公开了所有对象基类的属性(即QObject的属性),以及供应商或AUT(例如,通过子类化)添加的对象类型特定的属性,最后是Squish特别有用的某些人工属性。

通常情况下,任何对象的属性都可能在标识它时使用(例如,在调用Object findObject(objectName)Object waitForObject(objectOrName)函数时)。然而,只有非人工属性才适用于验证(例如,在调用Boolean test.compare(value1, value2)函数和其他test模块函数时)。

要了解对象的非人工属性是什么,可以查府对象在其工具包文档中的类型,或者使用Spy。要使用Spy,首先启动AUT(请参阅启动AUT操作),然后与AUT交互,直到相关的 AUT 对象可见。此时,切换到squishide并执行选择操作(请参阅应用程序对象视图);然后选择感兴趣的对象。现在,对象的全部非人工属性都将显示在属性视图中。要了解对象的人工属性,可在应用程序对象视图中对象上调用上下文菜单并将其实际名称复制到剪贴板:实际名称中未列在属性视图中的任何属性都是人工属性。

人工属性

属性名称工具包注释
aboveLabelmacOS, iPhone被识别对象上方标签的符号名称
aboveObjectWindows被识别对象上方对象的符号名称
aboveWidgetQt被识别对象上方小部件的符号名称
aboveWidgetTextQt被识别对象上方小部件持有的文本。需要指定上述WidgetType。
aboveWidgetTypeQt被识别对象上方小部件的类型
basetypeJavaJava工具包中比type更通用的替代品
buddyQt被识别对象关联的标签的符号名称
buddyNameQt被识别对象关联的标签的objectName
buddyTextQt被识别对象关联的标签的文本
columnQt被识别对象所位于的列(如果它在表或树等多值对象中)
columnNumbermacOS被识别对象所位于的列(如果它在表或树等多值对象中)
containerQt, macOS, iPhone, Windows包含被识别对象的对象的符号名称
containerLabelQt包含被识别对象的对象的文本标签
containerNameQt包含被识别对象的对象的名称(例如,标题)
containerTypeQt包含被识别对象的对象的类型
documentViewmacOS用于滚动条(NSScroller):被识别对象所在的文档视图的符号名称(即它滚动的视图)
isApplicationMenuItemmacOS用于菜单项(NSMenuItem):如果此属性为1,则菜单项是菜单栏中打开应用程序菜单的菜单项。对于所有其他菜单项,该属性为0。
左标签macOS, iPhone被识别对象左边标签的符号名称
左对象Windows被识别对象左边对象的符号名称
左控件Qt被识别对象左边控件的符号名称
左控件文本Qt被识别对象左边控件包含的文本。需要指定 leftWidgetType。
左控件类型Qt被识别对象左边控件类型
名称Qt被识别对象的 objectName
出现Qt, macOS, iPhone, Windows一个唯一标识一个对象的数字,该对象在其他情况下与其他对象相同(由于具有完全相同的属性值)
父项macOS被识别对象父对象的符号名称
右标签macOS, iPhone被识别对象右边标签的符号名称
Qt被识别对象在其内部的多值对象(如列表、表或树)中的行
行号macOS被识别对象在其内部的多值对象(如列表、表或树)中的行
tableViewmacOS被识别对象所属的 NSTableView 的符号名称
类型所有被识别对象类型的名称(或类)。对于大多数GUI工具包,必须在真实(多属性)名称中始终存在;然而,Squish for Windows 和 Squish for Web 不要求如此。
未命名Qt如果被识别对象没有 objectName,则此属性的值为 "1";否则,其值为 "0"
可见Qt, macOS, iPhone, Windows如果被识别对象在逻辑上可见(即,不是完全被一个或多个 AUT 对象遮挡),则此属性的值为 "1";否则,其值为 "0"。在针对原生 Windows 应用程序进行的测试中,此属性假设的值为 truefalse
窗口Qt、macOS、iPhone包含被识别对象的窗口的符号名称
窗口名称Qt包含被识别对象的窗口的名称(标题)
窗口出现Qt包含被识别对象的窗口的出现次数
窗口类型Qt包含被识别对象的窗口的类型

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