LDTP安装:
• 源码形式ldtp软件安装
下载
$gitclone git://anongit.freedesktop.org/git/ldtp/ldtp.git
安装
$./autogen.sh --prefix=/usr;make,然后su登录root用户
$make install
• 二进制形式ldtp
下载
http://download.opensuse.org/repositories/home:/anagappan/Fedora_10/i386/
安装
$rpm -i<包的名称>
下载LDPT帮助文档: LDTP Tutorial PDF / ODF
LDTP的结构和原理
LDTP整体结构图
测试脚本
LDTP客户端
LDTP引擎
AT-SPI Layer
Application under test
LDTP内部构造:
LDTP的客 户端通过LDTP命令转换协议(LDTPCTP)和LDTP引擎交互。现阶段我们是用嵌入python语言实现的LDTP命令转换协议,将来可能还会有基于mono/java/perl版本的。客户端和服务端的交互是以XML形式进行的。
大多数的LDTP命令需要两个参数,第一个是将要操作什么样的窗口,第二个是在设定的窗口里将要操作的对象
例如:click ('*-gedit', 'btnNew')
这个click操作将在一个开启了*-gedit (regexp)的窗口中进行,窗口中有一个名为“New”的对象,其类型为“pushbutton”
服务端:
当一个测试脚本开始执行时,LDTP客户端将会使用AF_UNIX / AF_INET建立一个与LDTP引擎的连接
客户端处理器:
一旦来自脚本的命令被执行,客户端就会构建XML数据并发送到服务端。LDTP引擎解析从客户端发来的请求,调用相应的组建处理器
组件处理器:
每个组件处理器通过AT-SPI仓库与各自相关的应用程序通信,它们会根据执行的情况,返回成功或失败(以XML格式)给客户端。在某些情况下,组件处理器会将索求的数据返回给客户端,这取决于客户端发出的是何种请求,比如:gettextvalue
事件处理器:
为了处理一些意外出现的窗口,比如连接超时的重置窗口,可以通过事件处理器为这样的窗口指定一个召回函数。只要这个被登记的窗口出现了,就算是处于非意外的情况下,相应的召回函数都会被调用。
记录器:
记录执行的状态(采取XML格式)
LDTP的惯用表达规则
Appmap[ApplicationMap]以文本的方式表述被测试的图形用户界面。所有的UI操作,即按钮、文本框等,都按照Appmap已经设定好的规则来表述,并附加上它们的父UI对象的信息。运行时,我们就可以通过Appmap来获取特定的UI操作。
Appmap预设规则列表见LDPT的pdf帮助文档的第11~13页
如何从脚本获取UI对象
两个要素: 窗口名称和 对象名称
窗口名称
> 窗口的不同类型:
1. Frame (frm)
2. Dialog (dlg)
3. Alert (dlg)
4. Font Chooser (dlg)
5. File Chooser (dlg)
6. Window (这种类型的窗口一般没有相关标题,所以我们需要通过索引 -dlg来表述它 )
> 表达式:
窗口标题可以用表达式的形式,以*和?号来取代一定的字符,如*-gedit'表示标题以-gedit结尾的窗口
> 表述窗口名称的不同方式:
1.窗口类型和窗口标题(如:'frmUnsavedDocument1-gedit')
2.窗口标题(如:'Unsaved Document 1 - gedit')
3.窗口类型,窗口标题表达式 (如: 'frm*-gedit',或'frmUnsavedDocument1*')
4.窗口标题表达式 (如: '*-gedit')
5.窗口类型,窗口标题和索引(如:若有两个标题相同的窗口,一个为'dlgAppoinment',另一个则为'dlgAppoinment1')
6.窗口类型和索引(如:'dlg0',仅在窗口没有任何可用标题的情况下)
> 窗口名称的格式:
窗口标签里出现空格或转行字符会被过滤,例如
1.'Unsaved Document 1 – gedit', 将被转换成'UnsavedDocument1-gedit'
2. 'Unsaved Document 1
-
gedit', 将被转换成'UnsavedDocument1-gedit'
对象名称
1>.对于 menu / menu item / push button /toggle按钮类,一般来说,我们通过它们的标签来获取,如:
mnuFile (gedit menu)
mnuNew (gedit menu item)
btnNew (gedit tool bar, push button)
tbtnLocation (gedit Open File dialog, toggle bar control)
2>.对于 text / tables/ check box / radio button / spin button /combo文本框类,一般来说,我们只能通过它们的相关标签来获取,如:
txtLocation (gedit Open File dialog, text control)
tblFiles (gedit Open File dialog, table control)
cboSearchfor (gedit Find dialog, combo box control)
chkMatchcase (gedit Find dialog, check box control)
sbtnRightmarginatcolumn (gedit Preferences dialog, spin buttoncontrol)
3>.而对于既没有标签又没有相关标签的对象,我们通过索引来获取,如:
txt0 (gedit text rendering region)
ptl0 (gedit Preferences dialog, page tab list control)
ptl0 (In gedit when more than one files are opened, a page tab listcontrol will be available)
4>.对于在一个窗口中多次出现的对象,我们可以在它们的名称里加上索引来获取,如:
btnAdd – First push button control with label Add
btnAdd1 – Second push button control with label Add
btnAdd2 – Third push button control with label Add
对象名称的格式
对象名称里出现的空格、点、冒号、下划线以及转行字符会被过滤,例如:
Search for:' 将被表述成 'Searchfor'
'File name 'a_txt' already exist.
Replace' 将被表述成 'Filename'atxt'alreadyexistReplace'.
AT-SPI(accessibilitylibraries)
我们需要启用gnome控制中心下的辅助技术(AssistiveTechnology),通过它我们可以得到应用程序的信息和状态。
导入LDTP模块
from ldtp import *
from ldtputils import *
我们以如上的方式而不是以'importldtp'导入的原因在于,这样我们就能直接使用ldtp功能的名称来调用它们,不然我们就得这样调用-ldtp.<fuction name> 。
示例 1:
from ldtp import *
selectmenuitem ('*-gedit', 'mnuFile;mnuNew')
示例 2:
import ldtp
ldtp.selectmenuitem ('*-gedit', 'mnuFile;mnuNew')
调用函数执行操作:
为了选中一个菜单,我们需要使用 selectmenuitem命令,例如,使用如下的命令选中gedit的打开菜单:
• selectmenuitem ('frmUnsavedDocument1-gedit','mnuFile;mnuOpen')
此命令会弹出一个新的对话框,这时你可以通过 guiexist (验证窗口存在否)或 waittillguiexist(缺省设定为等候30秒来确认窗口的存在与否)来判定此窗口是否是被打开的
如果想要获取窗口中一个按钮,我们需要使用 click命令
如果我们修改了一个用gedit打开的文件,此文件的标题也将会被改变。为了继续控制窗口,我们可以使用 setcontext 命令,不再需要时使用
releasecontext
编辑打开的文件使用:
• settextvalue ('frmUnsavedDocument1-gedit', 'txt0', 'Testingediting')
之前标题是 'Unsaved Document 1 - gedit' ,经过settextvalue后,标题将会变成'*Unsaved Document 1 - gedit'。如果我们还是想延用以前的窗口名称 ,使用:
• setcontext ('Unsaved Document 1 - gedit', '*Unsaved Document 1 -gedit')
这样的话我们就能继续使用同样的窗口名称,例如:
• selectmenuitem ('frmUnsavedDocument1-gedit','mnuFile;mnuSaveAs')
这个命令将会激活一个保存文件的对话框
LDTP的应用程序接口
已实现的LDTP API列表
LDTP具体操作示例见操作手册第18~36页
召回事件处理
当一个给定标题的窗口被创建时,我们可以给它指定一个召回事件。这样我们可以很简地处理掉意外出现的窗口,帮助手册第37页有一个很详细的例子
数据xml文件
xml文件保存了脚本在运行时要求的输入数据。
使用LDTP数据XML的优点
• 分离脚本和数据,实现复用
• 只需编写脚本一次,根据需求构造数据XML
• 某些回归测试我们只需要一个脚本和多个数据XML文件
• 选择XML格式的原因在于它很容易被解析
数据XML的标签
• data -完整的XML是被包裹在<data>和</data>标签里的
•<用户定义的标签>-用户定义的标签可以出现多次,伴有用户定义的取值。如果使用LDTP工具XML解析器,用户定义标签的取值将会以列表的形式返回,我们可以以索引来使用它。列表的索引从0开始
语法
LdtpDataFileParser('[XML Filename]')
LdtpDataFileParser类以XML的文件名为可选参数,它还提供了两个函数
● * setfilename ('[XML Filename]').如果LdtpDataFileParser类没有带参数,那么应该调用这个函数
● * gettagvalue ('tag name'). 取得提供的标签的值
例子:
Example 1
addr_book = LdtpDataFileParser ()
addr_book.setfilename ('evolution-ab.xml')
addr_book.gettagvalue ('AddressbookType')
Example 2
addr_book = LdtpDataFileParser ('evolution-ab.xml')
addr_book.gettagvalue ('AddressbookType')
XML文件的例子:
<data>
<AddressbookType>On ThisComputer<AddressbookType>
<AddressbookName>LDTP-AB</AddressbookName>
</data>
ldtprunnerXML文件
ldtprunnerXML文件的作用是通过把相关的脚本和对应的数据xml文件纳入一个集合,一次执行。如果其中的一个测试脚本失败了,则余下的脚本将不再执行。
使用LDTP数据XML的优点
• 相关测试脚本置于同一个目录下
• 在一个组里,当下在运行的脚本失败后,剩下未运行的脚本将会被跳过,ldtprunner将会执行下一个组
• 每个脚本可以把可选的data XML文件当作参数
• 同一个脚本对应不同data XML文件可以运行多次
• 脚本可以以任何顺序组合,脚本按照此顺序执行
ldtprunner的标签 (#表示为可选项)
• ldtp -完整的XML是被包裹在<ldtp>和</ldtp>标签里的
• logfileoverwrite# - 取值0(添加到已有的日志文件)或1(覆盖重写)
• logfile - 文件名,即日志文件将写入何处。日志文件是以XML格式生成的。最好输入文件的绝对路径。
• appmapfile# - 可选的文件名映射。此标签只对向后兼容的可用,不推荐使用 ???
• category# - 一个目录可以包含一个或多个组。同一目录下所有组的成员都会按一顺序执行。
• group -一个组可以包含一个或多个脚本。组里所有脚本将会按某一顺序运行。分组的目的是为了当一个脚本运行失败时,整个组可以跳过。
• testcaseid - 一个组有一个testcase id。如果可以,此id会作为日志文件的一部分被记录下来
• comment - 脚本的注释,不会被日志文件记录
• script - 脚本包含一个脚本文件名和可选的数据文件名
• name - 脚本文件名
• data# - 数据文件名(数据文件的内容为xml格式)
以下为生成ldtprunner XML时的建议
• 选择用ldtprunner XML初始化的日志文件
• 选择日志文件重写选项
ldtprunner XML 文件的例子:见帮助手册第41~42页
如何执行LDTP脚本
确认在你当下的工作目录里有如下文件:
•
可执行的测试脚本
•
data XML - 可选
•
ldtprunner XML - 可选
•
确认ldtp,ldtprunner,ltfx(可选),digwin(可选),ldtprecord(可选)已安装
调用 ldtprunner XML
$ ldtprunner<ldtprunner XML>
Example
ldtprunner test-runner.xml
调用python脚本
$ python<script file name.py>
Example
python gedit.py
• 源码形式ldtp软件安装
• 二进制形式ldtp
下载LDPT帮助文档: LDTP Tutorial PDF / ODF
LDTP的结构和原理
LDTP整体结构图
LDTP内部构造:
LDTP的客 户端通过LDTP命令转换协议(LDTPCTP)和LDTP引擎交互。现阶段我们是用嵌入python语言实现的LDTP命令转换协议,将来可能还会有基于mono/java/perl版本的。客户端和服务端的交互是以XML形式进行的。
大多数的LDTP命令需要两个参数,第一个是将要操作什么样的窗口,第二个是在设定的窗口里将要操作的对象
例如:click ('*-gedit', 'btnNew')
这个click操作将在一个开启了*-gedit (regexp)的窗口中进行,窗口中有一个名为“New”的对象,其类型为“pushbutton”
服务端:
当一个测试脚本开始执行时,LDTP客户端将会使用AF_UNIX / AF_INET建立一个与LDTP引擎的连接
客户端处理器:
一旦来自脚本的命令被执行,客户端就会构建XML数据并发送到服务端。LDTP引擎解析从客户端发来的请求,调用相应的组建处理器
组件处理器:
每个组件处理器通过AT-SPI仓库与各自相关的应用程序通信,它们会根据执行的情况,返回成功或失败(以XML格式)给客户端。在某些情况下,组件处理器会将索求的数据返回给客户端,这取决于客户端发出的是何种请求,比如:gettextvalue
事件处理器:
为了处理一些意外出现的窗口,比如连接超时的重置窗口,可以通过事件处理器为这样的窗口指定一个召回函数。只要这个被登记的窗口出现了,就算是处于非意外的情况下,相应的召回函数都会被调用。
记录器:
记录执行的状态(采取XML格式)
LDTP的惯用表达规则
Appmap[ApplicationMap]以文本的方式表述被测试的图形用户界面。所有的UI操作,即按钮、文本框等,都按照Appmap已经设定好的规则来表述,并附加上它们的父UI对象的信息。运行时,我们就可以通过Appmap来获取特定的UI操作。
Appmap预设规则列表见LDPT的pdf帮助文档的第11~13页
如何从脚本获取UI对象
两个要素: 窗口名称和 对象名称
窗口名称
> 窗口的不同类型:
1. Frame (frm)
2. Dialog (dlg)
3. Alert (dlg)
4. Font Chooser (dlg)
5. File Chooser (dlg)
6. Window (这种类型的窗口一般没有相关标题,所以我们需要通过索引 -dlg来表述它 )
> 表达式:
窗口标题可以用表达式的形式,以*和?号来取代一定的字符,如*-gedit'表示标题以-gedit结尾的窗口
> 表述窗口名称的不同方式:
1.窗口类型和窗口标题(如:'frmUnsavedDocument1-gedit')
2.窗口标题(如:'Unsaved Document 1 - gedit')
3.窗口类型,窗口标题表达式 (如: 'frm*-gedit',或'frmUnsavedDocument1*')
4.窗口标题表达式 (如: '*-gedit')
5.窗口类型,窗口标题和索引(如:若有两个标题相同的窗口,一个为'dlgAppoinment',另一个则为'dlgAppoinment1')
6.窗口类型和索引(如:'dlg0',仅在窗口没有任何可用标题的情况下)
> 窗口名称的格式:
窗口标签里出现空格或转行字符会被过滤,例如
1.'Unsaved Document 1 – gedit', 将被转换成'UnsavedDocument1-gedit'
2. 'Unsaved Document 1
对象名称
1>.对于 menu / menu item / push button /toggle按钮类,一般来说,我们通过它们的标签来获取,如:
mnuFile (gedit menu)
mnuNew (gedit menu item)
btnNew (gedit tool bar, push button)
tbtnLocation (gedit Open File dialog, toggle bar control)
2>.对于 text / tables/ check box / radio button / spin button /combo文本框类,一般来说,我们只能通过它们的相关标签来获取,如:
txtLocation (gedit Open File dialog, text control)
tblFiles (gedit Open File dialog, table control)
cboSearchfor (gedit Find dialog, combo box control)
chkMatchcase (gedit Find dialog, check box control)
sbtnRightmarginatcolumn (gedit Preferences dialog, spin buttoncontrol)
3>.而对于既没有标签又没有相关标签的对象,我们通过索引来获取,如:
txt0 (gedit text rendering region)
ptl0 (gedit Preferences dialog, page tab list control)
ptl0 (In gedit when more than one files are opened, a page tab listcontrol will be available)
4>.对于在一个窗口中多次出现的对象,我们可以在它们的名称里加上索引来获取,如:
btnAdd – First push button control with label Add
btnAdd1 – Second push button control with label Add
btnAdd2 – Third push button control with label Add
对象名称的格式
对象名称里出现的空格、点、冒号、下划线以及转行字符会被过滤,例如:
'File name 'a_txt' already exist.
Replace' 将被表述成 'Filename'atxt'alreadyexistReplace'.
AT-SPI(accessibilitylibraries)
我们需要启用gnome控制中心下的辅助技术(AssistiveTechnology),通过它我们可以得到应用程序的信息和状态。
导入LDTP模块
我们以如上的方式而不是以'importldtp'导入的原因在于,这样我们就能直接使用ldtp功能的名称来调用它们,不然我们就得这样调用-ldtp.<fuction name> 。
示例 1:
示例 2:
调用函数执行操作:
为了选中一个菜单,我们需要使用 selectmenuitem命令,例如,使用如下的命令选中gedit的打开菜单:
• selectmenuitem ('frmUnsavedDocument1-gedit','mnuFile;mnuOpen')
此命令会弹出一个新的对话框,这时你可以通过 guiexist (验证窗口存在否)或 waittillguiexist(缺省设定为等候30秒来确认窗口的存在与否)来判定此窗口是否是被打开的
如果想要获取窗口中一个按钮,我们需要使用 click命令
如果我们修改了一个用gedit打开的文件,此文件的标题也将会被改变。为了继续控制窗口,我们可以使用 setcontext
编辑打开的文件使用:
• settextvalue ('frmUnsavedDocument1-gedit', 'txt0', 'Testingediting')
之前标题是 'Unsaved Document 1 - gedit' ,经过settextvalue后,标题将会变成'*Unsaved Document 1 - gedit'。如果我们还是想延用以前的窗口名称 ,使用:
• setcontext ('Unsaved Document 1 - gedit', '*Unsaved Document 1 -gedit')
这样的话我们就能继续使用同样的窗口名称,例如:
• selectmenuitem ('frmUnsavedDocument1-gedit','mnuFile;mnuSaveAs')
这个命令将会激活一个保存文件的对话框
LDTP的应用程序接口
已实现的LDTP API列表
LDTP具体操作示例见操作手册第18~36页
召回事件处理
当一个给定标题的窗口被创建时,我们可以给它指定一个召回事件。这样我们可以很简地处理掉意外出现的窗口,帮助手册第37页有一个很详细的例子
数据xml文件
xml文件保存了脚本在运行时要求的输入数据。
使用LDTP数据XML的优点
• 分离脚本和数据,实现复用
• 只需编写脚本一次,根据需求构造数据XML
• 某些回归测试我们只需要一个脚本和多个数据XML文件
• 选择XML格式的原因在于它很容易被解析
数据XML的标签
• data -完整的XML是被包裹在<data>和</data>标签里的
•<用户定义的标签>-用户定义的标签可以出现多次,伴有用户定义的取值。如果使用LDTP工具XML解析器,用户定义标签的取值将会以列表的形式返回,我们可以以索引来使用它。列表的索引从0开始
语法
LdtpDataFileParser('[XML Filename]')
LdtpDataFileParser类以XML的文件名为可选参数,它还提供了两个函数
● * setfilename ('[XML Filename]').如果LdtpDataFileParser类没有带参数,那么应该调用这个函数
● * gettagvalue ('tag name'). 取得提供的标签的值
例子:
Example 1
Example 2
XML文件的例子:
<data>
</data>
ldtprunnerXML文件
ldtprunnerXML文件的作用是通过把相关的脚本和对应的数据xml文件纳入一个集合,一次执行。如果其中的一个测试脚本失败了,则余下的脚本将不再执行。
使用LDTP数据XML的优点
• 相关测试脚本置于同一个目录下
• 在一个组里,当下在运行的脚本失败后,剩下未运行的脚本将会被跳过,ldtprunner将会执行下一个组
• 每个脚本可以把可选的data XML文件当作参数
• 同一个脚本对应不同data XML文件可以运行多次
• 脚本可以以任何顺序组合,脚本按照此顺序执行
ldtprunner的标签 (#表示为可选项)
• ldtp -完整的XML是被包裹在<ldtp>和</ldtp>标签里的
• logfileoverwrite# - 取值0(添加到已有的日志文件)或1(覆盖重写)
• logfile - 文件名,即日志文件将写入何处。日志文件是以XML格式生成的。最好输入文件的绝对路径。
• appmapfile# - 可选的文件名映射。此标签只对向后兼容的可用,不推荐使用 ???
• category# - 一个目录可以包含一个或多个组。同一目录下所有组的成员都会按一顺序执行。
• group -一个组可以包含一个或多个脚本。组里所有脚本将会按某一顺序运行。分组的目的是为了当一个脚本运行失败时,整个组可以跳过。
• testcaseid - 一个组有一个testcase id。如果可以,此id会作为日志文件的一部分被记录下来
• comment - 脚本的注释,不会被日志文件记录
• script - 脚本包含一个脚本文件名和可选的数据文件名
以下为生成ldtprunner XML时的建议
•
•
ldtprunner XML 文件的例子:见帮助手册第41~42页
如何执行LDTP脚本
确认在你当下的工作目录里有如下文件:
调用 ldtprunner XML
调用python脚本