RF的WEB自动化编写指导
RF的Web自动化(UI)
产品规划及汽车新技术研究院 智能网联开发中心 互联网平台部
牛珊 2020/11/26
1. Robot Framework功能使用
RF是RobotFrameWork的简称,Robot Framework是一款python编写的功能自动化测试框架。具备良好的可扩展性,支持关键字驱动,因其自带很多已经编好的类库,能够很好地适应不同python基础的人来学习及使用,可以同时测试多种类型的客户端或者接口,可以进行分布式测试执行。主要用于轮次很多的验收测试和验收测试驱动开发(ATDD)
1、web自动化:主要指web页面的自动化工作
使用类库:Selenium2Library
优点:简单易学易编写
缺点:web脚本过多的依赖于网页元素的稳定性,后期维护会变的困难,且工作量大
2、接口自动化:主要指借助协议接口调用及数据传输和服务器交互的测试。分为REST接口自动化和SSH类api接口测试。REST接口自动化:使用HttpLibarary.HTTP库,通过http类协议做数据传输和服务器交互(pip install –upgrade robotframework-httplibrary )
SSH类api接口测试:使用SSHLibarary库,通过ssh协议连接服务器进行测试,
优点:稳定性、容错性较好,运行速度快,维护成本低
缺点:需要了解一定入门级的接口及网页编辑原理,上手较为困难
3、app类自动化:主要指适用于各类app自动化测试,如安卓系统,
使用类库:Appium
1.1 Ride功能介绍
1.1.1 创建工程
在本地任意目录创建一个文件夹,随后在ride里面打开这个文件夹例如:UITest
每个自动化工程建议有以下几部分以方便工程后期扩展及统一管理:(在这里创建的每一个目录都对应本地目录层级,也可以本地创建好目录后用RF打开)
测试用例目录:用于存放自动化脚本
测试数据目录:存放测试数据,如json文件,测试输入准备数据等
关键字目录:用于存放项目编写的公共方法及封装的关键字(方法)
用户自定义关键字目录(关键字目录的下一级):存放自己编写的一些py文件
变量目录:存放提前设置好的全局变量,用于后期引用
在脚本编写的时候根据用例的层级模型创建目录,同类脚本放在一个目录下,方便参数和关键字的引用具体过程如下。
1.1.2 创建目录和套件
1、 在工程目录上右键选择New Directory创建目录层级
完成目录创建后,新建测试套(NewSuite 单元)
1.1.3 创建脚本和界面简介
在上一步创建的测试套上右击新建脚本(New test case),创建完成后脚本界面如下,依次为:
RUN 脚本运行界面:控制脚本运行和运行日志导出查看的界面,在运行日志分析时详细说明
Text Edit 文档编辑界面:此界面是直接编辑脚本保存的txt文档以达到修改编辑脚本的目的(点开看一下就明白了!)
Edit 脚本编辑界面:当前截图所示界面,用以全面编辑脚本,设置前后置等
Settings 界面设置:管理脚本配套设置界面
Documentation 文档说明:此处用来说明脚本,一般用来存放完整用例以保证脚本忠诚度
Setup 脚本前置:脚本运行前运行的关键字,一般用来运行测试数据或环境准备
Teardown 脚本后置:脚本运行后运行的关键字,此处无论脚本运行结果成功与否都会执行,相当于编程语言中异常处理的finally语句块,一般用来清理测试数据和恢复测试环境
Timeout 超时时间: 脚本运行的超时时间,如果脚本运行时间大于这里设定的时间就会运行失败,标记block或者failed
Tags 脚本标记:批量运行时用于控制和识别脚本,有兴趣下来了解
Template 模板:脚本模板,用来限制参数数据?不太好懂,也比较少用,有兴趣下去了解
1.1.4 导入库和资源
Python中的库,点击library,在name里面添加库名称,点击保存,这个库就添加成功,前提是这个库已经成功安装在Python目录下
Resource是后期自定义的一些文件,用于存储公共关键字等文件,存放在项目目录中,选择后会相对路径的方式存在
1.1.5 编写及运行脚本
新建的测试脚本Test里面编写测试脚本
看下脚本运行界面,红框中是做启停等操作界面的输入键
红色箭头分别表示:
运行状态:绿色表示运行通过,红叉表示运行失败
Log :用于打开运行日志界面,是保存在本地的html文件
其他键位如其名
1.1.6 分析脚本的运行日志
在脚本运行失败后,我们要分析日志查看失败原因,一般失败会有以下三个问题引起:
1、问题:脚本状态及编写无问题,环境正常仍运行失败,说明索要执行的用例不通过,版本有问题,此时建议根据手动去验证结果
2、脚本问题:是因为脚本逻辑导致的代码运行错误,分析后调试脚本,确保脚本代码逻辑正确,运行稳定
3、环境问题:因脚本运行环境或产品服务器突发异常导致的脚本失败,修复环境后重新运行
4、复制log文件到浏览器里面查看日志的详细信息:
5、日志界,点击测试套/脚本对应的右边绿色条可以打开详细信息
根据对应的关键字运行信息进行脚本运行结果分析,
2. 定位元素
2.1 Selenium8中定位元素的方法
2.1.1 id定位
id定位: find_element_by_id()
从上面定位到的搜索框属性中,有个id="kw"的属性,我们可以通过这个id定位到这个搜索框
2.1.2 name定位
name定位: find_element_by_name()
从上面定位到的搜索框属性中,有个name="wd"的属性,我们可以通过这个name定位到这个搜索框
2.1.3 class定位
class定位:find_element_by_class_name()
从上面定位到的搜索框属性中,有个class="s_ipt"的属性,我们可以通过这个class定位到这个搜索框
2.1.4 tag定位
tag定位:find_element_by_tag_name()
如果懂HTML知识,我们就知道HTML是通过tag来定义功能的,比如input是输入,table是表格,等等...。每个元素其实就是一个tag,一个tag往往用来定义一类功能,我们查看百度首页的html代码,可以看到有很多div,input,a等tag,所以很难通过tag去区分不同的元素。基本上在我们工作中用不到这种定义方法,仅了解就行。
2.1.5 link定位
link定位:find_element_by_link_text()
此种方法是专门用来定位文本链接的,比如百度首页右上角有“新闻”,“hao123”,“地图”等链接
2.1.6 partial_link定位
partial_link定位:find_element_by_partial_link_text()
有时候一个超链接的文本很长很长,我们如果全部输入,既麻烦,又显得代码很不美观,这时候我们就可以只截取一部分字符串,用这种方法模糊匹配了。
2.1.7 xpath定位
xpath定位:find_element_by_xpath()
前面介绍的几种定位方法都是在理想状态下,有一定使用范围的,那就是:在当前页面中,每个元素都有一个唯一的id或name或class或超链接文本的属性,那么我们就可以通过这个唯一的属性值来定位他们。
但是在实际工作中并非有这么美好,有时候我们要定位的元素并没有id,name,class属性,或者多个元素的这些属性值都相同,又或者刷新页面,这些属性值都会变化。那么这个时候我们就只能通过xpath或者CSS来定位了。
2.1.8 css定位
CSS定位:find_element_by_css_selector()
这种方法相对xpath要简洁些,定位速度也要快些,但是学习起来会比较难理解,这里只做下简单的介绍。
2.2 Xpath定位元素
2.2.1 Xpath路径如何获取
解决:谷歌F12打开检查界面,点击箭头,然后定位到该元素,右键-》copy->copy Xpath
随后就copy出来一个
但是这种xpath只要界面位置变动,就需要重新复制
2.2.2 Xpath简介
什么是xpath
XPath 使用路径表达式在 XML 文档中进行导航
XPath 包含一个标准函数库
XPath 是 XSLT 中的主要元素
XPath 是一个 W3C 标准
XPath 路径表达式
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
2.2.3 Xpath语法之选取节点
可以看下如下的xpath路径的编写方式,如果不会,可以模仿着写,这种不会因为位置的变动有非常大的改变,例如:
//*[@name='loginname']
//*[@type='submit']
//span[contains(text(),'${username}')]
//div[contains(text(),’在线客服’)]
//a[@title='选择年份']
//a[contains(@class,'mz-calendar-month-panel-month') and text()='${m1}月']
//div[contains(text(),’在线客服’)]/../div/div//input
//a[contains(text(),’在线客服’)]/../div/div//li[1]
表达式 |
描述 |
nodename |
选取此节点的所有子节点。 |
/ |
从根节点选取。 |
// |
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. |
选取当前节点。 |
.. |
选取当前节点的父节点。 |
@ |
选取属性。 |
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。下面列出了最有用的路径表达式:
路径表达式 |
结果 |
bookstore |
选取 bookstore 元素的所有子节点。 |
/bookstore |
选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book |
选取属于 bookstore 的子元素的所有 book 元素。 |
//book |
选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book |
选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang |
选取名为 lang 的所有属性。 |
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
2.2.4 Xpath语法之谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 |
结果 |
/bookstore/book[1] |
选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] |
选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] |
选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] |
选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] |
选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] |
选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] |
选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]//title |
选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
2.2.5 Xpath语法之选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 |
描述 |
* |
匹配任何元素节点。 |
@* |
匹配任何属性节点。 |
node() |
匹配任何类型的节点。 |
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 |
结果 |
/bookstore/* |
选取 bookstore 元素的所有子元素。 |
//* |
选取文档中的所有元素。 |
//title[@*] |
选取所有带有属性的 title 元素。 |
2.2.6 Xpath语法之选取若干路径
通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 |
结果 |
//book/title | //book/price |
选取 book 元素的所有 title 和 price 元素。 |
//title | //price |
选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price |
选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
3. 脚本编写进阶
3.1 创建关键字和公共方法
3.1.1 创建关键字
在文件夹右键点击,创建一个resource文件,随后在resource文件右键,new user keyword,这个就是封装一个用户的关键字
如下,由于登录会在很多地方使用,所以封装成一个登录的关键字
3.1.2 使用关键字
在Login测试套件里面的setting中,添加resource文件,commonkeywords.robot添加进去
随后,在testcase里面,可以直接使用这个关键字,引用了的关键字为蓝色,未引用的是黑色。
3.1.3 Py文件的方法
当前库里的关键字没有办法满足写脚本的时候,可以自己写一个方法,随后把这个processMonitor.py文件作为library导入到rf中进行使用
下图为这个processMonitor.py文件中的脚本
引用processMonitor.py文件
使用这个processMonitor.py文件中的方法
3.2 创建公共变量
在Test_var下创建一个resource文件
随后在resource文件下右键,创建一个new scalar文件
填写数据如下,在当前的项目底下,都可以引用url,前提是要把resource文件引用,就可以正常使用公共变量
在另外的文件下应用公共变量
3.3 Selenium2Library关键字
3.3.1 常用关键字
1、 log就是“print”robotframework中,log关键字就是编程语言里的“print”一样,可以打印任何你想打印的内容 如:log hello world
2、 open browser打开浏览器
3、 Click Button [ locator ] 点击被'locator'标识的按钮。
4、 Click Element [locator]点击被'locator'标识的元素。
5、 Close All Browsers [ ]关掉所有打开的浏览器,并且重置这些浏览器的缓存;这个关键字被执行之后,从'Open Browser'关键字返回的新的索引被重置为1;这个关键字应该被用在test或者suite的teardown中,以确保所有浏览器被关闭
6、 Close Browser [ ]关闭当前运行的浏览器。
7、 input text 在文本框中录入内容
8、 input password 在文本框中录入密码
9、 click button 点击按钮
10、 page should (NOT)contain (link,button,element,checkbox,list) 页面是否出现指定的内容
11、 下拉列表select from list xpath value
select from list by value xpath value
select from list by index xpath value
12、 选中框架select frame
取消框架unselect frame
13、 复选框select checkbox id=CheckYes
取消复选框unselect checkbox id=CheckNo
14、 单选框select radio button radio1---单选框名称
15、 等待页面加载wait until page contains element
16、 休息sleep
17、 reload page---刷新
18、 注释Comment
3.3.2 其他关键字
1、 Add Cookie [ name | value | path=None | domain=None | secure=None | expiry=None ]给你当前的会话增加一个cookie。"name"和"value","path","domain"和"secure"是可选项。
2、 Alert Should Be Present [text=]验证Alert是否存在并且消除它。如果'text'不是空字符串,它会验证alert上的信息是否与'text'一致。
当然,如果alert不存在,测试将会失败。注意,除非通过这个关键字或者别的关键字像'Get Alert Message'消除alert,否则后面执行的关键字会失败。
3、 Assign ID [ locator | id ]分配一个临时的标识符给一个元素,首先通过'locator'来定位这个元素。当定位该元素的Xpath表达式很复杂时,这种方法非常有用。此外,当页面重新载入时,这个标识符就到期了。
4、 Capture Page Screenshot [ filename=None ]在当前页面上截屏,并把它放在日志里。'filename'参数指定了一个元素的名称并把截屏写入。如果没有提供'filename',截屏将会被保存在'selenium-screenshot-<counter>.png'文件中,该文件就在RF日志文件被写入的目录下。'css'可以被用来改变截屏的执行方式。当页面布局以某种方法被破坏时,可通过改变默认的背景颜色去避免可能的背景泄露问题。
5、 Checkbox Should Be Selected [ locator ]验证'locator'标识的checkbox是否被选定。
6、 Checkbox Should Not Be Selected [ locator ]验证'locator'标识的checkbox没有被选定。
7、 Choose Cancel On Next Confirmation [ ]下次'Confirm Action'被使用时,撤销将会被选定。
8、 Choose File [ locator | file_path ]将'file_path'写入被标识的文件写入区域。这个关键字被经常使用去将文件写入到上传表格中。由'file_path'指定的文件必须存在于Selenium Server 运行的主机上。
9、 Choose Ok On Next Confirmation [ ]取消使用'Choose Cancel on Next Confirmation'这个关键字的影响。注意,Selenium的重写window.confirm()函数通常会自动返回true,就好似用户手动的点击OK,所以你应该不需要这个命令,除非你需要改变你的next confirmation的首选项因为某些原因。在任一confirmation之后,Selenium将会为未来的confirmatons恢复使用默认值,自动的返回true(OK)除非你明确的对每一个confirmation使用'Choose Cancel On Next Confirmation'。还要注意每次一个confirmation开始时,你必须使用'Get Alert Mseeage'等类似的关键字,不然selenium接下来的操作将会失败。
10、 Click Element At Coordinates [ ]点击被'locator'标识的元素,以该元素的x/y坐标为基准。鼠标移动到该元素的中心,x/y坐标就从那一点被计算出来。
11、 Click Image [ ]点击被'locator'标识的图片。
12、 Click Link [ ]点击被'locator'标识的链接。
13、 Close Window [ ]关闭当前弹出的窗口。
14、 Confirm Action [ ]关闭当前显示的会话并返回它的信息。这个关键字会默认选择会话中的'OK'。如果需要选择‘Cancel’,关键字'Choose Cancel On Next Confirmation'必须在引起确认会话被显示的行为之前被调用。
15、 Current Frame Contains [text|loglevel=INFO]核实当前frame是否包含'text'。
16、 Current Frame Should Not Contain [text|loglevel=INFO]核实当前frame是否包含'text'。
17、 Delete All Cookies []删除所有cookies。
18、 Delete Cookie [name]删除匹配'name'的cookie。如果这个cookie没有被发现,什么事都不会发生。
19、 Double Click Element [locator]双击被'locator'标识的元素。
20、 Drag And Drop [source|target]拖拽被'source‘ (实际是一个'locator')定位的元素。元素可被移动到其它目标元素之上。'target'是一个元素定位器,指定了拖拽住的元素松开的位置。
21、 Drop And Drop By Offset [source|xoffset|yoffset]拖拽被'source‘ (实际是一个'locator')定位的元素。元素将会被移动到坐标xoffset和yoffset指定的位置。坐标可以是正数也可是负数。
22、 Element Should Be Disabled [locator]验证被'locator'指定的元素是否可用。
23、 Element Should Be Enabled [locator]验证被'locator'指定的元素是否可用。
24、 Element Should Be Visible []验证被'locator'指定的元素是否可见。这里,可见指的是逻辑可见,而不是在当前浏览器窗口上的视觉可见。举个例子,一个元素呈现为none,那么该元素就是逻辑上不可见的,所以在这个元素上使用此关键字将会失败。
25、 Element Should Contain [loactor|expected|message=]验证被'locator'定位的元素是否包含文本'expected'。如果你想要在元素的文本里断言一个精确的匹配而不是一个子串,使用关键字'Element Text Should Be'。'message'可被用于覆盖默认的错误信息。
26、 Element Should Not Be Visible [locator|message=]验证被'locator'定位的元素是不可见的。是关键字'Element Should Be Visible'的反义。'message'可被用于覆盖默认的错误信息。
27、 Element Text Should Be [locator|expected|message=]验证被'locator'定位的元素是否精确的包含文本'expected'。与'Element Should Contain'形成对比,这个关键字不是在被'locator'标识的元素上尝试子串匹配,而是精确匹配。
28、 Execute Async Javascript [*code]执行异步JS代码。'code'可能含有很多行代码,但是最后必须包含一个返回状态(即要有返回值)。'code'也许在测试数据中被分成很多单元。即便如此,彼此关联的部分不允许增加任何空间。如果'code'是一个指向一个存在的文件的完整的路径,JS将从这个文件中读取并执行。分隔号'/'用于所有操作系统的路径分隔。注意,默认地,代码将会在Selenium对象自己的环境中执行。所以,'this'将会适用于the Selenium 对象。使用'window'去适用于你的应用的窗口。例如,'window.document.getElementById('foo')'.
29、 Execute Javascript [*code]执行提供的js代码。
30、 Focus [locator]设置被'locator'定位的元素为焦点。
31、 Frame Should Contain [locator|text|loglevel=INFO]验证被'locator'定位的'frame'是否包含'text'。
32、 Get Alert Message []返回当前js alert里的内容。如果当前没有alert,这个关键字将会失败。注意,接下来的关键字将会失败除非alert通过这个关键字或者'Get Alert Message'被消除。
33、 Get All Links []返回一个列表,该列表包含当前页面所有链接的id。如果一个链接没有id,这个列表将含有一个空的字符串。
34、 Get Cookie Value [name]返回名称为'name'的cookie的值。如果没有cookie叫'name',这个关键字失败。
35、 Get cookies []返回当前页面的所有cookie。
36、 Get Element Attribute [attribute_locator]返回元素属性的值。属性定位器'attribute_locator'由标识@和属性名称组成,如"element_id@class"
37、 Get Horizontal Position [locator]返回被'locator'定位的元素的水平位置。位置作为正数类型被返回到页面左侧的像素位置。如果没有找到匹配的元素,将会失败。
38、 Get List Items [locator]从已被'locator'定位select list中返回值。Select list 关键字工作在每个列表和组合框中。select list的关键属性是'id'和'name'。
39、 Get Location []返回当前的位置。
40、 Get Matching Xpath Count [xpath]返回匹配'xpath'的若干元素。如果你想断言若干匹配的元素,使用'Xpath Should Match X Times'.
41、 Get Selected List Label [locator]从被'locator'定位的select list中返回可见的选项元素的标签。Select list 关键字工作在每个列表和组合框中。select list的关键属性是'id'和'name'。
42、 Get Selected List Labels [locator]从被'locator'定位的select list中返回可见的选项元素的标签(作为一个列表)。如果没有选项将会失败。
43、 Get Selected List Value [locator]从被'locator'标识的的select list中返回选中的元素的值。返回值被选中的元素的'value'属性读取。Select list 关键字工作在每个列表和组合框中。select list的关键属性是'id'和'name'。
44、 Get Selected List Values [locator]从被'locator'标识的的select list中返回选中的元素的值(作为一个列表)。返回值被选中的元素的'value'属性读取。Select list 关键字工作在每个列表和组合框中。select list的关键属性是'id'和'name'。
45、 Get Selenium Implicit Wait []获取Selenium隐式等待时间。
46、 Get Selenium Speed []获取每一条执行Selenium命令时的延迟等待时间。
47、 Get Selenium Timeout []在短时间内获取timeout,被不同的关键字使用。
48、 Get Source []从当前页面或框架返回整个html源。
3.4 RF使用小技巧及问题
3.2.1 关键字联想
不清楚关键字全称的时候,可以输入几个单子,随后点击Ctrl+Alt+Space联想,如下图
3.2.2 查看库内所有的关键字
在RF中点击F5,出现搜索关键字的显示框,可以在里面对每个库的关键字进行查看以及搜索
3.2.3 定位不到元素1
定位不到元素,很有可能是因为前段页面有iframe挡住了
解决方法:
先从最里面的元素开始一级一级往上找,找到iframe,然后先select frame这个ID就可以定位到里面的元素了。
3.2.4 定位不到元素2
1、xpath定位一个button,不生效
解决:该元素不是一个button,需要用click element
不要使用Click Button关键字-严格来说,该关键字适用于该<button>类型的html元素。
而是使用Click Element-您的目标元素是<a>,然后Click Elements浏览器将对其执行单击
原本Click Button //*[@id="app"]/div[1]/div[2]/ul/li[2]/a
改成Click Element xpath=//*[@id="app"]/div[1]/div[2]/ul/li[2]
2、 页面操作按钮提示找不到elements
click button id=carInfoSubmitBtn
改为click element id=carInfoSubmitBtn
3、 InvalidElementStateException: Message: u'Element must not be hidden, disabled or read-only'出现这个现象是因为脚本执行快,而页面的元素还没有加载完成造成的
解决方案:等待页面加载wait until page contains element或sleep
4、
5、
6、
3.2.5 /html开头的xpath路径
需要在签名加上Xpath=
根据录入框内容弹出框框,定位不到元素,采用相对路径的方式定位,用firefox浏览器打开地址,按F12获取元素位置,右击---选择复制XPATH
放在脚本中形式为:xpath=/html/body/div[9]/div[2]/table/tbody/tr[4]/td[4]
3.2.6 进程中很多chromedriver.exe进程
把上述文件放在当前项目的自定义文件夹下,随后在脚本中引用
引用方式为:processMonitor.Find Killproc
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?