robotframework学习笔记
确保 Python 3.6.2 安装成功
安装 如下 RF使用中需要的工具和库
RF
在两个Python中安装 robotframework
执行命令 pip install robotframework
seleniumlibrary
在两个Python中安装 seleniumlibrary
执行命令 pip install --upgrade robotframework-seleniumlibrary
3.pycharm安装插件
在Pycharm中,点击菜单 file - settings - plugins
在弹出对话框中 点击下方 按键 Browse Repository
在新对话框中, 搜索栏里面输入 robot
安装 下面3个插件
IntelliBot
IntelliBot @SeleniumLibrary Patched
Run Robot framework file
下载 IntelliBot插件
https://github.com/jcyrss/songqin-testdev/raw/master/others/softwares/intellibot.jar
在Pycharm中,点击菜单 file - settings - plugins
在弹出对话框中 点击下方 按键install plugin from disk
选择下载的jar文件
根据视频,将如下 自动化用例 拷贝到 一个 名为 baidu.robot的文件中,然后用 robot命令行 运行一下
*** Settings ***
Library SeleniumLibrary
*** Test Cases ***
百度搜索松勤
Open Browser http://www.baidu.com chrome
Set Selenium Implicit Wait 5
Input Text id=kw 松勤\n
${firstRet}= Get Text id=1
Should Contain ${firstRet} 松勤网
pip install --upgrade robotframework-seleniumlibrary
1 套件和用例的结构
把功能相关的测试用例组合起来放在一起,成为某个测试套件,测试套件相当于一个目录,还可以其他测试套件,可以放测试套件文件,也叫测试数据文件(test data file),可以有多个用例,用例只会存在测试套件文件里,不会存在目录里
只要以号开头,就是一个表,robotframework可以识别,但是插件无法识别,所以还是需要前后三个号
测试用例名称一定到顶在最前面,空格两个以上 意思就是不同列,第二列
RF支持四种表:分别为Settings, Variables, Test Cases, Keywords
表名必须出现在第一单元格中,表名大小写不敏感,一般 首写字母大写
Settings表,是这个测试套件的全局配置表,比如,说明这个测试套件要试用的测试库、资源文件,测试套件的环境初始化(setup)和清除(teardown),该套件内的标签等等,导入库是最常用的
在用例内导入的库只在用例里生效,放在settings表中,则不需要每个用例中声明
Variables表,就是存放这个测试套件的全局变量表
Keywords表,是用来定义这个测试套件的用户关键字的
Test Cases表,是用来定义这个测试套件的测试用例的,大概可以分为两个部分:
配置部分
主体部分
用例配置部分:
[Documentation] 指该用例的文字说明
[Tags] 指该用例的标签
[Setup] , [Teardown] 指该用例的初始化和清除操作
[Template] 声明该用例是模板关键字驱动的,本用例只包含测试数据
[Timeout] 设置用例超时时间
用例的主体部分主要是用关键字组成的
关键字的来源:测试库(有的是自己开发的,有的robotfroamework内置的,有的是第三方开发的)、测试文件(用户关键词,用robotframework自己定义的,非Python或者java开发的)、用例所在文件的关键字表
关键字的使用
RF的常用关键字在RF标准库中() RF官方文档:http://robotfroamework.org
standard #标准库 装好robotwork就自带的
builtin #内置库,最常用的,不需要import
external #处理对话框的
collections #处理列表或者字典类的
关键字set variable:定义变量,通常是字符串,用法:
${var} set variable hello 或者
${var}= set variable hello
还可以赋值给多个(三个、四个、五个等等)变量:
${var1} ${var2} set variable hello world
v a r s e t v a r i a b l e 5 这 时 候 {var} set variable 5 这时候 varsetvariable5这时候{var}是一个字符串
关键字和参数should be equal(first,second,msg=None,values=True,ignore_case=False)
first,second 为必填参数,是作为两个python对象即字符串来进行比较的
msg=None 默认可以不填,如果没有该参数,出错的时候会给提示:first!=second
*** Test Cases ***
搜索松勤
${var} set variable hello
should be equal ${var} helle
Rf2 | FAIL |
1 critical test, 0 passed, 1 failed
1 test total, 0 passed, 1 failed
如果添加了该参数,除了会给出提示first!=second,前面还会给出自己写的参数内容,例如:
*** Test Cases ***
测试1
${var} set variable hello
should be equal ${var} helle 变量不是hello
Rf2 | FAIL |
1 critical test, 0 passed, 1 failed
1 test total, 0 passed, 1 failed
如果想让first,second 作为数字进行比较,可以用关键字should be equal as integers,例如:
*** Test Cases ***
测试1
should be equal as integers 10 010
运行结果:pass
log to console #只打印在终端窗口
log:打印在日志里
convert to integer # 将字符串转换为浮点数,例如:
*** Test Cases ***
测试1
${num} convert to integer 32
log to console ${num}
#定义一个变量时默认是字符串,通过convert to integer 将其转变为浮点数了
convert to number #将字符串转换为整数,例如:
*** Test Cases ***
测试1
${num} convert to number 32
log to console ${num}
#定义一个变量时默认是字符串,通过convert to number 将其转变为整数了
如果不需要定义变量,而是在某一个关键字里使用一个数字作为其参数,可以这样使用,因为出现的不是变量就会被当做字符串:
log to console ${32} #这时候传给log to console的就是数字32
定义一个空字符串的方法:
*** Test Cases ***
测试1
${num} set variable ${empty}}
log to console ${num}
定义一个数字变量
测试1
${var} set variable ${89}
log to console ${var}
should be equal 10 010 #字符串对象比较,结果是false
should be equal as integers 10 010 #转换成数字对象比较,结果是True
注意:should be true 参数是一个python表达式,然后rf会把这个表达式传递给python解释器是解释执行,解释这个表达式是够正确,例如:
*** Test Cases ***
测试1
s t r s e t v a r i a b l e h e l l o s h o u l d b e t r u e ′ {str} set variable hello should be true ' strsetvariablehelloshouldbetrue′{str}’ ‘hello’
还可以这么写:
*** Test Cases ***
测试1
${str} set variable hello
should be true $str hello
如果用should be equal,就是这样:
*** Test Cases ***
测试1
${str} set variable hello
should be equal ${str} hello
通常,关键字是由测试库提供的,测试库就是python模块文件,python测试库里面的关键字的实现方式主要有:类的方法、函数、RF脚本使用函数名、方法名(大小写不敏感) 库名字区分大小写
RF中可以导入python模块文件,导入后可以使用其中的函数、方法名作为关键字
RF如何发现库路径的:和python程序一致,sys.path
补充知识点:python 内置函数repr() 作用是可以打印出变量的本身类型的结果,比如说 a = ‘123’ ,print(repr(a))的结果即是‘123’
print是显示在log文件中的
库的导入
除了builting库,无需导入声明,其它库必须要声明导入,库的导入方式:
在用例中使用关键字import Library导入
在settings表中声明导入
库导入的时候的参数
Library SeleniumLibrary 10 20
RF中的变量
RF中的变量,实质上就是一个python变量,RF变量对应的是什么Python对象,它就是什么类型的对象,RF中,对变量有不同的用法:
Scalar方式
${var}
直接把变量所对应的python对象传递给关键字 对应的函数
假如传进去的既有变量也有字符串,RF会把变量先转换成字符串,再和另一个字符串拼接起来,例如:
*** Test Cases ***
测试1
s t r s e t v a r i a b l e a b c l o g t o c o n s o l e h e l l o , {str} set variable abc log to console hello, strsetvariableabclogtoconsolehello,{str}
List方式
假设 v a r 是 一 个 列 表 变 量 如 果 是 以 {var}是一个列表变量 如果是以 var是一个列表变量如果是以{var}这种方式传入,那么它还是一个列表
如果是以@{var}这种方式传入,那么是展开list中的每个元素,作为多个参数传入,可以指定取其中某一个,比如:
@{var}[0] 代表取的是列表中的第一个元素
Dictionary方式
&{var}
展示Dict中的每个元素,作为多个参数传入,可以指定取某个key值,比如:
&{var}[ele1]
传入环境变量,可以用:
%{path}
Collection标准库
针对List和Diction的处理,创建并添加元素,数字变量${1} ${2}
创建列表
*** Settings ***
Library Collections
*** Test Cases ***
测试1
${list} create list ${1}
append to list ${list} hello
log to console ${list}
打印结果:
测试1 [1, ‘hello’]
| PASS |
还可以添加多个元素:
*** Settings ***
Library Collections
*** Test Cases ***
测试1
${list} create list abc dfg
append to list ${list} hello world
log to console ${list}
创建字典
*** Settings ***
Library Collections
*** Test Cases ***
测试1
${dict} create dictionary abc dfg
set to dictionary ${dict} hello world ${1} ${2}
log to console ${dict}
循环
RF没有while循环,用For来实现循环,主要是:
Example 1
:FOR ${animal} IN cat dog
\ log to console ${animal}
\ log to console 2nd keyword
log to console outside loop
打印结果:
Example 1 cat
2nd keyword
dog
2nd keyword
outside loop
| PASS |
遍历list变量
Example 2
${list}= create list hello world
:FOR ${VAR} IN @{list}
\ log to console ${var}
IN RANGE的用法,相当于Python中的range,IN RANGE一定要大写
IN RANGE用法
[Documentation] loops over values from 0 to 9
:For ${var} IN RANGE 10
\ log to console ${var}
打印结果:
IN RANGE用法 :: loops over values from 0 to 9 0
1
2
3
4
5
6
7
8
9
| PASS |
一个检查学科的例子
经典方法
evaluate方法
1 条件判断:run keyword if (condition,keyword)
如果condition成立,condition是一个python表达式,那么就执行keyword,如果有多个,就用AND连接,keyword即是关键字
run keyword if ‘2018’ in $html log to console 2018年的,UTC时间
如果条件不满足,但是还是会pass,只是不执行keyword
如果需要换行,加英文下三个点:…
如果要和ELSE一起使用:
run keyword if ‘2018’ in $html … log to console 2018年的,UTC
… ELSE log to console 不是2018年的
2 ELSE分支:
run keyword if ‘2018’ in $html … log to console 2018年的,UTC
… ELSE IF ‘2017’ in $html log to console 2017年
… ELSE log to console 不是2018年的
run keyword unless:
run keyword if ‘2018’ in $html log to console 2018年的,UTC时间
run keyword unless ‘2018’ in $html log to console 不是2018年的,UTC时间
与Python不同的是:run keyword unless不一定前面要run keyword if
最新的版本里run keyword if,会对ELSE参数做判断
Dialogs库经常用于半自动化,比如输入验证码
关键字 get value from user 获取用户输入的内容
*** Settings ***
Library Dialogs
*** Test Cases ***
practice
${weight} get value from user 请输入你的体重 60
log to console ${weight
RF中没有while循环,只能用IN RANGE加上一个很大的数字,比如:
:FOR ${one} IN RANGE 999999999
退出循环:exit for loop
evaluate关键字 后面可以直接用python表达式定义变量
*** Test Cases ***
测试1
${var} evaluate 89
log to console ${var}
定义列表:
*** Test Cases ***
测试1
${var} evaluate [‘hello’,1]
log to console ${var}
初始化和清除(自动化框架最重要的一个点)
Setup是测试一个用例(或者套件)前要做的事情
Teardown是测试后测试环境要清除的事情
在RF中,每个测试套件目录、测试套件文件、测试用例都可以有自己的Setup和Teardown
所有的Setup和Teardown操
作都只能由一个关键字语句构成
测试用例的Setup、Teardown
写在测试用例表中的配置项中
*** Test Cases ***
测试1
[Setup] log to console \n ***acse st setup ****
log to console 测试用例主体部分
[Teardown] log to console \n *** case st teardown ****
测试套件文件的初始化和清除:写在测试套件文件的Settings表中
两种类型:
Suite Setup
Suite Teardown
进入和退出这个Suite执行用例前后必须执行且只分别执行一次,即先执行套件初始化Suite Setup,再执行用例,如果用例里有[Setup]和[Teardown],就等其执行完后再执行套件清除Suite Teardown
Test Setup
Test Teardown
用的比较少,缺省的用例初始化和清除,即如果Suite内的用例本身没有[Setup],[Teardown],才执行,如果都有,先执行测试套件的初始化和清除,再执行用例初始化[Setup]、[Teardown],执行完用例,再执行清除Test Setup、Test Teardown也可以放在套件的初始化settings中,如果下面有用例没有自己的[Setup]、[Teardown],可以使用套件的初始化Test Setup、Test Teardown
套件目录的初始化和清除:在其目录下的初始化文件_init_.txt或者_init_.robotl里的,有效范围是下面所有的子目录,执行方式:robot 套件目录名称
Settings表中
两种类型:
Suite Setup
Suite Teardown:进入和退出这个Suite执行用例前后必须执行且只分别执行一次
Test Setup
Test Teardown:只针对用例,如果Suite内的用例或者子套件本身没有Setup、Teardown,才执行,如果目录文件和套件文件里面都有初始化Test Setup、Test Teardown,那么就近原则,只执行测试套件文件里的Test Setup和Test Teardown,注意执行完测试套件文件后,要注意看是否有测试套件清除Suite Teardown,有的话就要执行完才能执行下一个测试套件文件,整个目录下的文件都执行完了的话,再执行目录的清除Suite Teardown.
注意:所有的测试用例一定要从根开始执行如果需要执行某个目录下的测试套件文件可以用:
robot --suite st1 suite1 #suite指的套件(固定词),suite1是目录文件
指定两个:
robot --suite st1 --suite st2 suite1
通常从测试库也就是python文件里面的提供的关键字,我们叫库关键字
还可以在RF文件中实现关键字,这种关键字我们称之为用户关键字
用户关键字类似于RF层面的函数,把多个关键字操作组成一个‘宏’关键字
定义好用户关键字后,该测试套件里面就可以使用该用户关键字了,就像使用库关键字一样
定义、使用用户关键字
首先我们要创建关键字表
用户关键字的定义和定义一个用例写法非常的像
keywords表
*** Keywords ***
login_addcourse_check #关键字名,相当于函数名
[Arguments] ${coursename} ${coursedesc} #关键字参数,相当于函数参数
资源文件
在测试套件文件中定义关键字的问题,只能在本测试套件中有效,无法共享给其他测试套件使用
使用资源文件
资源文件其实就是RF层面的库文件:
里面可以包含用来共享的变量和关键字
资源文件的格式基本也和测试套件文件类似,除了不能有测试用例表,其他都可以有,比如:
*** Settings ***
Library SeleniumLibrary
Library Collections
Library dec.py
*** Keywords ***
log_in
[Arguments] ${username} ${password}
open browser http://localhost/mgr/login/login.html chrome
set selenium implicit wait 5
input text id=username ${username}
input text id=password ${password}
click element css=button[class=“btn btn-success”]
add_course
[Arguments] ${courasename} ${coursedesc} ${courseidx}
click element css=button[ng-click=“showAddOne=true”]
input text css=input[ng-model=“addData.name”] ${courasename}
input text css=textarea[ng-model=“addData.desc”] ${coursedesc}
input text css:input[ng-model=“addData.display_idx”] ${courseidx}
click element css:button[ng-click=“addOne()”]
搜索规则:
当前用例文件所在的目录
如果找不到,就在Python的模块搜索路径中搜索
用例里如果声明需要用资源文件,则用Resource 资源文件名称 #资源文件名称一定要加.robot后缀,例如:
*** Settings ***
Library SeleniumLibrary
Library Collections
Resource rc.robot
*** Test Cases ***
用例1:
[Setup] deleteAllCourse
[Teardown] deleteAllCourse
log_in auto sdfsdfsdf
add_course Python Python描述 3
${course}= list_courseresult
should be true $course == ['Python']
close browser
exit for loop if 后面接python表达式
evaluate 后面接python表达式
变量表中声明变量,一般是用于配置项中的
首先我们要创建variables,如果放在测试套件文件中,作用范围就是该测试套件文件下的所有用例
*** Variables ***
${mgrloginurl} http://localhost/mgr/login/login.html
${studentloginurl} http://localhost/student/login/login.html
如果我们定义的不是字符串
List变量
*** Variables ***
@{database} 127.0.0.1 3306 #注意@符号代表的就是一个列表
Dict变量
*** Variables ***
&{user} username=auto password=sdfsdfsdf
#注意&符号,代表的是一个字典
例子:
*** Variables ***
${mgrloginurl} http://localhost/mgr/login/login.html
${studentloginurl} http://localhost/student/login/login.html
@{database} 127.0.0.1 3306
&{user} username=auto password=sdfsdfsdf
*** Test Cases ***
case 1
log to console ${mgrloginurl}
log to console ${database}[0]
log to console &{user}[username]
如果需要共享使用,可以放到资源文件里,注意资源文件里不能有用例
RF使用变量文件
也可以使用Python模块文件提供公共变量给RF适用,只需要直接定义变量就可以,语法完全就是python,例如:
新建一个python文件:ariable.py如下:
database = [‘127.0.0.1’,‘3306’]
user = {‘username’:‘auto’,‘password’:‘sdfsdfsdf’}
那么如果需要在测试套件文件中声明中使用该python文件里的变量,则是:
*** Settings ***
Variables cfg.py #相对路径
*** Test Cases ***
*** Test Cases ***
case 1
log to console ${database}[0]
log to console &{user}[username]
变量文件声明的时候,可以使用绝对路径,也可以使用相对路径
使用相对路径的时候,RF搜索规则和资源文件搜索规则一样:
先在相对当前文件的目录,匹配搜索
在python的模块搜索路径中搜索,可以使用–pythonpath参数,命令如下:
robot --pythonpath . testcase\rf6.robot
那么引用python文件变量的时候写明该文件相对于项目的根目录路径
python扩展关键字
python模块作为测试库,提供关键字,比如python模块叫MyLibrary,对应的python文件是MyLibrary.py。那么测试库名字就是MyLibrary
定义在python模块文件中的函数, 名称前有_前缀的不能作为关键字,比如:
def returnlist():
return [1,2]
def _retutnlist(): #名称前有_的函数名称在python中约定俗称作为隐藏函数只在本模块文件可见
return [1,2]
还可以给关键字取别名,例如:
from robot.api.deco import keyword
@keyword(‘Hello’)
def returnlist():
return [1,2]
#那么该关键字returnlist就改为Hello了
python类作为测试库
比如python文件是tlib2.py,引用的时候就是库模块名称.类名称,例如:
*** Settings ***
Library tlib2.SubLibrary
class SubLibrary:
def returnint(self):
return 3
如果有该类有初始化方法,那么在引用该类的时候会生成一个实例化,且该类有初始化方法意味着引用的时候会调用该方法,而且该类有参数时,一定要传参,否则会报错,在导入的时候加参数
*** Settings ***
Library tlib2.SubLibrary localhost 80
该类中的成员方法, 名称前有_前缀的不会作为关键字
导入时的参数,对应类的初始化方法
如果类和模块文件同名,声明的时候就可以省略后面的类名,比如模块名称是SubLibrary.py,类名是SubLibrary,那么导入的时候只写模块名SubLibrary即可。
python扩展库的搜索规则
完全是按照python的模块的搜索规则来的,如果在包内abc/dic/variable.py
声明
*** Settings ***
Library abc.dic.variable 或者
Library abc/dic/variable.py
Library abc.dic.variable只会在Python模块搜索路径中去找
所以通常执行的就是以下命令:
robot --pythonpath . tc #tc是目录文件
关键字大小写不敏感,但是库名字大小写是敏感的
在settings中声明资源文件和变量文件:
路径,目录之间的分隔符,不用点. 而是用斜杠/
在settings中声明测试库:
路径,目录之间的分隔符,可以用点. 也可以用斜杠/
路径分隔符用点.后面不加py,用斜杠后面加.py
使用变量文件
也可以使用Python模块文件提供公共变量给RF使用,只需要直接定义变量就可以了,语法完全就是Python
RF声明使用变量文件
*** Settings ***
Variables dec.py
变量文件声明的时候,可以使用绝对路径,也可以使用相对路径。
使用相对路径的时候,RF搜索规则和资源文件搜索规则一样
现在相对当前文件的目录,匹配搜索
在Python的模块搜索路径中搜索,可以使用–pythonpath参数
命令行参数指定变量文件
robot --pythonpath . tc\t1.robot
Python扩展关键字
Python模块作为测试库
模块文件名作为测试库的名字
比如python模块叫MyLibrary,对应的Python文件是MyLibrary.py。那么测试库名字就是MyLibrary
定义在Python模块文件中的函数,名称前有_前缀的不会作为关键字
Python类作为测试库
比如Python文件是tlib2.py
class SubLibrary:
def returnint(self):
return 3
def _returnint2(self):
return 4
声明
Settings
Library tlib2.SubLibrary
该类中的成员方法,名称前有_前缀的不会作为关键字
导入时的参数,对应类的初始化方法
如果类和模块文件同名,声明的时候就可以省略后面的类名
已经接触到的项目文件种类有:
测试套件文件、目录
RF资源文件
测试库
变量文件
建议的自动化项目的目录结构:
首先是创建一个项目目录叫task
下面创建一个目录pylib放Python测试库,建议放一个初始化文件__init__.py,可以为空
再创建一个目录rflib放资源文件
再创建一个tc目录,放测试套件文件,再创建一个老师管理和一个课程管理的目录,里面放测试套件文件,当然tc下面还可以有多个子目录根据不同功能存放
最后再创建一个config.py放配置文件,如果配置文件过大时,可以创建一个目录
以robot --pythonpath . tc命令执行tc下面所有的用例
builtin库里面的Run Keywords方法后面以AND连接多个关键字实现初始化
RF用例的执行
robot [option] data_sources
#options 是RF命令的选项,可以为空
#data_sources则是要执行的测试套件文件或者目录的路径,可以是绝对路径,也可以是相对路径,相对于当前shell的工作目录,比如:
robot tests.robot
robot path/to/my_tests/ #相对路径
robot c:\robot\tests.robot #绝对路径
RF可以指定多个要执行的测试套件文件、目录,甚至用通配符来表示多个测试,例如:
robot my_tests.robot your_tests.robot
#同时执行测试套件或者目录my_tests和your_tests
robot --pythonpath . --name 回归测试 tc
#用–name选项来指定本次测试名称,指定本次测试名称为回归测试
根据名称选择测试用例
我们可以通过–test --suite来指定执行哪些用例或者套件,suite可以是测试目录也可以是测试套件,而且还支持用通配符的方式
–test example #执行名为example的用例
–test mytest --test yourtest #执行名为mytest和yourtest的用例
–test example* #执行名字以example开头的用例
–test *example #执行名字以example结尾的用例
–test example #执行名字只要包含example的用例,所以建议给用例名称加上编号比如测试用例1-0001,可以根据编号来选择执行用例,导出测试用例编号和我们的手工测试编号对应
–suite mysuite #执行名为mysuite的套件
参数文件
如果有的时候,参数太长,我们通常可以使用参数文件,我们可以把所有的参数都放在参数文件中,比如:
–pythonpath .
–name 回归测试
–test *tc00001
–test *tc00002
–test *tc00003
–test *tc00004
–test *tc00005
t1.robot
命令就只需要robot -A argfilename #-A表示执行什么参数文件,argfilename 即参数文件,比如:
robot -A args.txt
因为导入一个类作为测试库时,每次导入库时都会生成一个实例对象,比如SeleniumLibray作为一个类每次如果不做特殊处理时,每次导入时都会生成一个新的实例对象,
如果想在selennium里面想共享一个浏览器(webdriver)对象时,就不能每个都实例化,如果要在selenium里面做的话就那么就需要在类里面加上ROBOT_LIBRARY_SCOPE = ‘GLOBAL’,那么再导入的时候就只会生成一个实例
导入库时可以不用加.py
E:\python+selenium+robotframe\robotframework2\task>robot --pythonpath . tc
robot --pathonpath . --loglevel DEBUG tc
RF调试代码,可以在运行配置项设置,
可以新建一个配置项robotrun
Script path:C:\Python36\Lib\site-packages\robot\run.py
或者选择Module name:robot.run
Parameters: robot --pythonpath . --loglevel DEBUG tc #loglevel DEBUG也可以不写
Working directory: d:\tmp\rf8\task #项目的根目录
就可以在py文件开发的测试库里执行了
测试用例可以根据任何一个用例标签来过滤用例
RF打标签的方式
测试套件或者目录Setting表里的Force Tags #Force Tags后面可以写tag名称,代表该套件目录或者套件文件下的用例都有该有tag
该套件里面所有测试用例都具有了该tag
测试用例表里的[tags]配置
测试套件或者目录Setting表里的Default Tags
该套件里面没有[tags]设置的测试用例,都具有了该Default Tags
测试目录里面的__init__.robot不支持Default Tags,不可以设置,Default Tags用比较少
根据标签选择测试用例
–incuede foo #执用例行包含标签‘foo’的用例
–exclude foo #执行不包含标签‘foo’的用例
–include one AND"web test" #执行包含标签‘one’或者‘two’的用例
–include oneORtwo #执行包含标签‘one’或者‘two’的用例
–include oneNOTtwo #执行包含标签‘one’但是不包含‘two’的用例
–include w*w #执行标签格式为以w开头中间任何字符w结尾的用例
指定关键测试用例:
如果这次测试有关键测试用例没有通过,那么整个测试就被视为测试不通过,反之,整个测试就被视为通过
缺省情况下,RF执行测试时,每个测试用例都被视为关键测试用例
我们可以通过命令参数 --critical(-c)和–nocritical(-n)后面加tag名称来指定测试用例是否为关键测试用例
–critical regression 指定只有具有regression标签的用例才是关键用例,比如以下命令:
robot–include web测试 --critical critical webtest #web测试是初始化文件Settings表里的标签,critical是用例标签,webtest是测试套件目录
—nocritical not_ready指定不具有not_ready标签的用例是关键用例,其他用例都不是关键用例
–critical ok* --nocritical tbd*指定具有以ok开头的标签且没有以tbd开头的标签的用例都是关键用例,其他用例都不是关键用例
通常我们可以在关键用例上打上标签,比如basic表示是关键用例
实战目的
综合性运用学到的知识、巩固知识点
包括:python、Selenium、web API接口测试、Robot Framework
启发同学工作中自动化开发
个人简历中加上项目经验
json本身是一个字符串,只是字符串里面是符合json格式的语法,json里面可能是字典格式的也可能是列表形式的
API接口自动化
三个步骤
分析需求文档、包括:需求说明,接口文档
编写测试用例
执行测试,包括:手动测试、自动化
选型:
框架Robot Framework
开发语言Python
项目目录结构:
整个项目的目录结构
用例目录设计原则:
根据功能点
根据数据环境(最好是根据数据环境来构建目录,因为功能点不同导致可能数据初始化的浪费)
根据数据环境设计的用例目录
可以自己先建一个tc测试套件目录
再在该目录下建一个目录d-空白数据,下面对应有一个__init__.robot初始化环境,代表了在该目录下的测试套件用例或者测试套件目录是处于空白数据环境的
d-空白数据目录下可以建d-1班,代表该数据环境下只有一个1班,该目录下面的初始化文件_init__.robot[Setup]就是创建一个1班[Teardown]就是清除1班,如果你的用例需要的环境是只有一个1班就把用例放在这里
d-1班下可以再创建一个目录d-老师jcy,代表该数据环境下只有一个1班和一个老师jcy,该目录下面的初始化文件__init__.robot就只需要创建一个老师jcy,如果你的用例需要的环境是只有一个1班一个老师jcy就可以把用例放在这里
d-老师jcy下面可以在创建一个目录d-有学生stu1-stu2,代表该数据环境下只有一个1班和一个老师,学生stu1-stu2,该目录下面的初始化文件__init__.robot就是创建stu1-stu2,如果你的用例需要的环境是只有一个1班一个老师jcy和学生stu1-stu2就可以把用例放在这里
#目录名称可以自己定,其中上面d代表有做数据环境的设置,每个测试套件要负责执行完退出之前在[Teardown]把数据清除掉,还原到进入之前的数据环境
如果定义的某个函数还没有实现,可以用pass来占位,如:
def classlist_should_contain(self):
pass
检查添加的课程是否存在,可以在pylib中通过以下函数实现检查点:
def classlist_should_contain(self,classlist,calssname,gradename,invitecode,studentlimit,studentnumber,classid):
item = {
"name": calssname,
"grade__name": gradename,
"invitecode": invitecode,
"studentlimit": int(studentlimit),
"studentnumber": int(studentnumber),
"id": int(classid),
"teacherlist": []
}
if item not in classlist:
raise Exception('班级列表中不存在该班级')
一个测试单元执行结束时,必须要和执行前的数据环境一致:
测试套件目录执行结束后,要和执行前一致
测试套件文件执行结束后,要和执行前一致
测试用例执行结束后,要和执行前一致
RF初始化文件和资源文件里都可以有除了测试用例以外的表
如何在测试套件目录初始化文件里删除添加的课程,有以下办法:
RF中设置变量:Set Global Variable(self,name,*values)
#第一个参数name就是定义的全局变量的名字,第二个*values参数是变量的值,那么就可以在初始化文件里清除要得到的值了,如下:
*** Keywords ***
suite setup aciton
${ret}= add school class 1 1班 60
set global variable ${suite_g7c1_classid} &{ret}[id]
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup suite setup aciton
Suite Teardown delete_school_class ${suite_g7c1_classid}
还可以在添加课程时记录下该课程id作为RF的全局变量,然后再在RF中引用该变量,该方法非常重要,以后会经常使用到,比如:
#先在python中导入库
from robot.libraries.BuiltIn import BuiltIn
#再在添加课程时定义一个变量idSaveNanme记录该课程id号,该变量为非必填项=idSaveNanme=None
def add_school_class(self,gradeid,name,studentlimit,idSaveNanme=None):
payload = {
'vcode' : self.vcode,
'action' : 'add',
'grade' : int(gradeid),
'name' : name,
'studentlimit' : int(studentlimit),
}
response = requests.post(self.URL,data=payload)
bodyDict = response.json()
pprint (bodyDict,indent=2)
if idSaveNanme:
BuiltIn().set_global_variable('${%s}' % idSaveNanme,bodyDict['id'])
return bodyDict
最后再在测试套件目录初始化文件中,使用该全局变量
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup add_school_class 1 1班 60 idnum
Suite Teardown delete_school_class ${idnum}
#idnum也可以是传入的一个字段或者列表,如果传的是字典,那么下面Suite Teardown删除的班级号就需要取出来,如下:
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup add_school_class 1 1班 60 idnum
Suite Teardown delete_school_class &{idnum}[id]
将Python对象转换成json格式的字符串,可以import json
json.dumps() 可以实现,例如:
a = [1,2,3]
import json
json.dumps(a)
‘[1, 2, 3]’
a = [{‘id’:1},{‘id’:2}]
json.dumps(a)
‘[{“id”: 1}, {“id”: 2}]’
json.loads刚好将其反过来,将json格式的字符串转换为python对象
第1、2节项目实战
项目主要功能:
在线作业
同步课学习
统计分析
管理功能:
系统标签
资源管理
学校管理
API接口自动化
三个步骤,
分析需求文档,包括需求说明,接口文档
编写测试用例
执行测试,包括手动测试,自动化
选型:
框架robotframework
开发语言python
做项目的时候,构建一个自动化的目录结构
根据功能点和数据环境来构建
1、在写测试用例的,尽量把相同功能点的测试用例的编号放在一起,那么不同功能点之间应该预留一部分编号,以便为剩余用例预留编号空间。
2、进入测试单元(测试目录、文件、用例)的数据环境要与退出时的数据环境保持一致,所以测试套件如果有setup一定要有teardown
第一种方法:
在关键字表中设置一个全局变量
例子:
*** Keywords ***
suite setup action
${ret} add school class 1 1班 60
set global variable ${suite_g7c1_classid} &{ret}[id]
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup suite setup action #注意这个地方不要写错
Suite Teardown delete_school_class ${suite_g7c1_classid}
第二种方法:
首先在测试库中导入:
from robot.libraries.BuiltIn import BuiltIn
然后再指定的函数中增加如下代码:
例子:
def add_school_class(self,gradeid,name,studentlimit,idsavename=None):
payload = {
‘vcode’ : self.vcode,
‘action’ : ‘add’,
‘grade’ : int(gradeid),
‘name’ : name,
‘studentlimit’ : int(studentlimit),
}
response = requests.post(self.URL,data=payload)
bodyDict = response.json()
pprint (bodyDict,indent=2)
if idsavename:
BuiltIn().set_global_variable('${%s}'%idsavename,
bodyDict['id'])
return bodyDict
测试套件内的初始化文件中可以这样写:
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup add school class 1 1班 60 suite_g7c1_classid #这个就是要传入的变量值,名字可以自定义命令
Suite Teardown delete_school_class ${suite_g7c1_classid} #这个要加{} 它指向的是一个字符串对象
说明:idsavename是参数名,为了让其他用例能够用这个全局变量,使用参数传入的方式
默认为空,可以 不传入,如果不为空就传入一个变量值,这个变量值将指向指定的对象,且是全局变量
这样,在套件文件中即可使用该全局变量。
第1节、2节robotframework 初识
robotframework是一个通用型的自动化测试框架
框架。就是实现特定需求的软件的解决方案工具包
测试框架还解决什么问题
自动测试用例的实现方式与开发支持
和用例管理系统的集成
测试执行:
执行规则
初始化和清除工作
报告生成
测试人员开发测试数据文件对应一个一个的测试用例
测试数据文件里面使用的功能小模块叫关键字,由测试库实现
robotframework加载测试库,并解释执行测试用例
以关键字的形式来开发测试用例
库的来源:标准库
第三方库
角色:
自动化测试库的开发
自动化测试用例的开发
RF 的安装
pip install robotframework 不用UI测试,只需要安装该库即可
RIDE 的安装(不支持python3,开发未维护的,网上目前有个支持pyhton3 的版本,但bug较多,暂不使用它)
注意:安装pyhton2 使用32位版本
一个简单的IDE
可视化的编辑功能
pip2 install robotframework-ride python3不支持
安装过程中如果提示:
Fatal error in launcher: Unable to create process using ‘"’
可以使用
python2 -m pip install --upgrade --force-reinstall pip #重新安装pip即可
wxpython 的安装, —RIDE 依赖wxpython 图形库 2.8.13
wxpython下载并安装:
https://github.com/jcyrss/songqin-testdev/raw/master/others/softwares/wxPython2.8-win32-unicode-2.8.12.1-py27.exe
seleniumlibrary 的安装,用于UI测试
支持selenium 自动化RF扩展库
pip2 install --pre --upgrade robotframework-seleniumlibrary
SeleniumLibrary库的帮助文档:
http://robotframework.org/SeleniumLibrary/SeleniumLibrary.html
pycharm 插件IntelliBot 的安装
很多熟手宁愿直接编辑RF测试数据文本文件
ride图形工具的使用,是新手使用的。
robotframework优点:
初始化清除
报表生成
用例选择机制
缺点:
没有python编程灵活。
最大的问题是用表格式的开发给不会代码的人提供了方便,但是对于比较复杂的自动化还不是很方便
关键字可以用python语言进行封装。
把复杂的步骤封装成库,然后robotframework调用库
使用pycharm开发用例,要安装一个插件:pycharm插件IntelliBot
文件系统中的每个目录都是一个测试套件,每个测试套件下面可以建立一个测试套件文件,测试用例是放在
测试套件文件中的。
关键字可以大小写,值不可以大小写
作业:
RF
在两个Python中安装 robotframework
执行命令 pip install robotframework
seleniumlibrary
在两个Python中安装 seleniumlibrary
执行命令 pip install --pre --upgrade robotframework-seleniumlibrary
RIDE
在Python2中安装 RIDE
执行命令 pip2 install robotframework-ride -i https://pypi.douban.com/simple/
wxpython
下载并安装
https://github.com/jcyrss/songqin-testdev/raw/master/others/softwares/wxPython2.8-win32-unicode-2.8.12.1-py27.exe
注意,安装到D:\tools\python2\Lib\site-packages下面
pycharm插件IntelliBot
下载 IntelliBot插件
https://github.com/jcyrss/songqin-testdev/raw/master/others/softwares/intellibot.jar
在Pycharm中,点击菜单 file - settings - plugins
在弹出对话框中 选择 install plugin from disk
选择下载的jar文件
第3、4节套件、用例、关键字
robot 支持HTML格式记录测试用例,tsv
套件和用例的结构
测试套件是测试用例的集合:
套件可能是一个目录或者文件,
把功能相关的测试用例组合起来放在一起,成为某个测试套件
功能相近的测试套件又可以组成一个更大的套件
就像文件和目录的关系一样,形成一个树形结构
套件和用例的结构:
在RF中:
自动化测试用例是放在测试套件文件中的,
一个测试套件文件可以包含多个测试用例
测试套件文件又叫测试数据文件
测试套件文件所在目录,称为测试套件目录
测试套件目录又可以包含其他测试套件目录。
一般,测试套件文件和测试套件目录对应的磁盘文件目录名,就是测试套件名
test suite 文件格式
可以用纯文本编辑器进行编辑
编码格式一定要用utf8格式,缺省为utf8、文件扩展名是.robot
支持其他文件格式来记录测试用例,比如HTML,tsv 和一种restucturedtext 格式的文件
ride不可以实时刷新,不可以复制、粘贴
推荐还是纯文本格式进行编辑。
以下格式不是固定的但最好是这样写、表名大小写不敏感、
*** Settings *** #全局配置项
功能:
存放配置项的,比如要使用的测试库,资源文件、环境初始化、清除,该套件内的标签等
*** Test Cases ***
这里出现红色破浪线是正常的,
用例的名字要在第一列,顶到最左边
用例的内容从第二列开始的
前面要留几个空格,一般默认是4个,至少2个
列与列之间隔2个以上的空格才是第二列的内容
如果文本框中包含空格,可以这样 :松勤 \ \ \网
加注释的快捷键:Ctrl+\
RF支持4种格式的表:
分别为Settings ,variables,Test Cases,Keywords
套件文件中的表
Test Cases表,是用来定义这个测试套件的测试用例,可以写多个测试用例
[Documentation] #该用例的文字说明
[Tags] #该用例的标签
[Setup],[Teardown] #该用例的初始化和清除工作
[Template] #声明该用例是模块关键字驱动的,本用例只包含测试数据
[Timeout] #设置用例超时时间
Variables 表,就是这个测试套件的全局变量表
Keywords表,是用来定义这个测试套件的用户关键字的
关键字的来源
测试库
资源文件 :用RF语法开发的关键字
用例主体部分 也包含变量赋值
关键字在第三列,通常是获取函数的返回值,并给后面使用
变量一般使用 ${}= 格式,
如果直接使用变量,可以这样
${ver}= Set variable (设置一个变量) 2
如果返回值有多个,返回的是一个元组。
关键字的使用:
最常用的是标准库中的关键字
变量如果没有加任何标记,就是作为字符串传入
*value 表示可变参数,参数个数是不确定的
**value 表示关键字可变参数,使用的时候加上参数名等于 就可以了
log关键字: #显示在日志文件中
例子:
测试1
${var} set variable 这是日志里面要记录的内容
Log ${var}
log to console关键字 #显示在屏幕上
例子:
测试1
${var} set variable 这是日志里面要记录的内容
log to console ${var}
${num}= convert to integer 32 #convert to integer:转换成浮点数32
log to console ${num}
${num2}= convert to Number 32 #convert to Number:转换成整数32
log to console ${num2}
Should Be Equal As Integers 010 10 #全部转换成数字对象比较,结果是true
第5、6节测试库、变量、循环
认识测试库
通常,关键字是由测试库提供的
测试库就是python模块文件
python测试库里面的关键字的实现方式:
类的方法
函数
RF脚本使用函数名,方法名。大小写不敏感
自定义的库在pycharm中导入的时候,寻找该库和python中import 某一个库的寻找
的方式是一样的。
库的导入
除了builtin 库,无需导入声明
其他库必须要声明导入
库的导入方式:
在用例中使用关键字import library导入
在settings表中声明导入
库导入时候的参数
Library Selenium2Library 15
Library Selenium2Library 0 5
Library Selenium2Library 5 run_onfailure=Log source
如果是自定义的库或类的方法,在初始化中定义了一些参数。也可以直接拿来用
RF中的变量
实质就是一个python变量
${var} #声明这是一个变量 叫做scalar 它传递的就是变量所指向的对象本身
如果传入的字符串是hello, v a r 1 混 合 在 一 起 的 。 那 么 闲 {var1} 混合在一起的。那么闲 var1混合在一起的。那么闲{var1}先转换成string,然后和前面
的内容进行拼接在一起。再传给关键字
list方式
@{var} #展开list中的每个元素,作为多个参数传入
可以进行取值操作
例子:
测试
${var1} returnlist
printarg @{var1}
或
测试
${var1} returnlist
printarg @{var1}[0] #按索引进行取值操作
&{var1}
例子:${var1} #对象必须是字典
{‘ele1’: ‘male’, ‘ele2’: ‘female’} #返回值
例子:&{var1} #对象必须是字典
‘ele1’:‘male’
‘ele2’:‘female’ #返回值
例子:&{var1}[ele1] #对象必须是字典,且传入的是key值.不需要加引号
‘male’ #返回的是value
例子:@{var1} #对象必须是字典
‘ele1’
‘ele2’ #返回值是key
取出环境变量:
%{path}
第7、8节条件判断、初始化、清除
Run keyword if 相当于 if
run keyword if ‘2017’ in $html log to console 内容
参数放在下一行
${var} getWebInfo
run keyword if ‘2018’ in $var log to console 2018年的
代码换行:
测试1
${var} getWebInfo
run keyword if ‘2018’ in $var
… log to console 2018年的 #…表示换行操作
ELSE 分支:
run keyword if xxxxxxxxx条件成立的时候做的事情xxxxxxxxxxxxxx
run keyword unless xxxxxxxxx当条件不成立的时候做的事情xxxxxxxxxxx
以上需要把run keyword if 再写一遍,或者不写上面,直接写下面这个。相当于if not xxx
新的写法:
run keyword if xxxxxxxxx条件成立的时候做的事情xxxxxxxxxxxxxx #这里可以多个条件用and 链接
… ELSE IF xxxxxxxxx当上面条件不成立的时候做的事情xxxxxxxxxxx
… ELSE xxxxxxxxx当上面条件不成立的时候做的事情xxxxxxxxxxxxxx #ELSE 要大写
半自动化的时候可能用到。比如判断下页面有没有图标、页面乱不乱。
测试1
:FOR ${one} IN RANGE 999999
\ w e i g h t = g e t v a l u e f r o m u s e r 请 输 入 你 的 体 重 60 L o g T o C o n s o l e 体 重 为 {weight}= get value from user 请输入你的体重 60 \ Log To Console 体重为 weight=getvaluefromuser请输入你的体重60 LogToConsole体重为{weight}
\ Exit For Loop if $weight=='over' exit for loop #相当于break
\ run keyword if int($weight)>60 log to console 太重 ELSE log to console 太轻了
:FOR ${one} IN RANGE 999999
\ w e i g h t = g e t v a l u e f r o m u s e r 请 输 入 你 的 体 重 60 L o g T o C o n s o l e 体 重 为 {weight}= get value from user 请输入你的体重 60 \ Log To Console 体重为 weight=getvaluefromuser请输入你的体重60 LogToConsole体重为{weight}
\ run keyword if $weight==' continue' continue for loop #相当于continue
也可以直接写: continue for loop if $weight==' continue'
当某个条件成立的时候,调出循环,可以:
Exit For Loop if $weight==' continue' #相当于continue
\ run keyword if int($weight)>60 log to console 太重 ELSE log to console 太轻了
如果if 中还有if 可以把这段代码封装在函数中,然后在robot 中直接调用
evaluate
直接用python代码来生成一个结果:
${var}= set variable ${152}
完全可以写成:
${var}= evaluate 890
复杂的表达式
${var } evaluate [‘hello’]*10
set up 初始化 测试一个用例前要做的事情
teardown 清除 是测试后要做的事情
在RF中,每个测试套件,测试套件文件,测试用例,都可以有自己的setup 和 teardown
所有的setup和teardown 都只能有一个关键字语句构成
测试用例的setup ,teardown
写在测试用例表的配置项
不管用例通过不通过,清除都会执行
例子:
*** Test Cases ***
测试1
[Documentation] 测试初始化、清除
[Setup] log to console \n *** 测试用例1 setup ****
log to console 测试用例1主体部分
[Teardown] log to console \n *** 测试用例 1 teardown ****
测试套件文件的setup、teardown
写在测试条件文件的settings表中
两种类型
suite setup/teardown #进入和退出这个sutie执行用例前后必须执行且分别执行一次。
例子:
*** Settings ***
Library …//lesson4//mylib4.py
Suite Setup log to console \n — Suite st2 Setup —
Suite Teardown log to console \n — Suite st2 Teardown —
*** Test Cases ***
测试1
[Setup] log to console \n *** case 测试1 setup ****
log to console 测试用例主体部分 11
[Teardown] log to console \n *** case 测试1 teardown ****
测试2
log to console 测试用例主体部分22
测试3
log to console 测试用例主体部分33
Test setup/teardown
如果suite内的用例,本身没有setup、teardown,才执行
例子:
*** Settings ***
Suite Setup log to console \n — Suite st Setup —
Suite Teardown log to console \n — Suite st Teardown —
Test Setup log to console \n — Test st Default Setup —
Test Teardown log to console \n — Test st Default Teardown —
*** Test Cases ***
测试1
[Setup] log to console \n *** case st setup ****
log to console 测试用例主体部分11
[Teardown] log to console \n *** case st teardown ****
测试2
log to console 测试用例主体部分22
测试3
log to console 测试用例主体部分33
测试套件目录的setup、teardown
例子:
lesson4/suite1
第9节、10节作业讲解、用户关健字和资源文件
注意:在对数据进行添加和删除和修改操作时,注意元素的顺序由于二次渲染的问题,可能已经发生改变。
解决方法:添加、删除、修改元素后,使用time.sleep(1)或者 sleep(1)
*** Keywords ***
什么是用户关键字。通常的从测试库也就是python文件里面提供的关键字。我们叫做库关键字
还可以在rf中实现关键字。称为用户关键字。rf层面的关键字
用户关键字类似于RF层面的函数,把多个关键字操作组成一个“宏”关健字
定义好用户关键字后,该测试套件里面就可以使用该用户关键字了,就像使用库关键字一样。
定义,使用用户关键字,首先我们要创建关键字表
用户关键字的定义和定义一个用例写法非常的雷同。
封装技巧:把常用的动作封装成用户关键字
资源文件,在测试套件文件中定义关键字的问题
只能在本测试套件中有效,无法共享给其他测试套件文件使用
使用资源文件
资源文件其实就是RF层面的库文件
里面可以包含用来共享的变量和关键字
资源文件的格式基本也和测试套件文件类似,不可以有测试用例表
Settings
Library
Resource rc1.robot
搜索资源文件的规则:
首先匹配搜索当前文件所在的目录,如果找不到。就在python的sys.path环境
变量所在的路径中搜索。
变量表中声明变量
首先我们要创建variables 表
variables
List变量
@{database} 127.0.0.1 3306
Dict 变量
&{usr1} name=auto pw=sdfsdfsdf
使用变量文件
也可以使用python模块文件提供公共变量给RF使用,只需要直接定义变量就可以了
语法完全就是python的语法
RF声明变量文件
settings
variables cfg.py
变量文件声明的时候,可以使用绝对路径,也可以使用相对路径
使用相对路径的时候,RF搜索规则和资源文件搜索规则是一样的,
命令行参数指定变量文件
robot --variablefile cfg\cfg.py tc\t1.robot
在pythonpath中找,
d:\tmp\rf>robot --pythonpath . tc\t1.robot
或者
d:\tmp>robot – pythonpath rf rf/tc/t1.robot
python扩展关键字
python模块作为测试库
模块文件名作为测试库的名字
比如python模块名叫mylibrarym,对应的python文件名是mylibrary.py.那么测试库名字就是mylibrary
定义在python模块文件中的函数,名称前有_前戳的不会作为关键字。
def rerutnlist():
return [1,2]
def _returnlist():
return[1,2]
要保证其在python模块的搜索路径中,这样RF才能找到它,
直接设置环境变量 set pythonpath=lessson6
用–pythonpath参数
RF使用关键字的时候
中间可以加上任意的空格
大小写也可以任意
returnlist
return list
Rerurn list
python类作为测试库
比如python文件是tilib2.py
class subibrary:
def rerutnlist(self):
return 3
def _returnlist2(self):
rerurn 4
声明:
Settings
library tlib2.subibrary
该类中的成员方法。名称前有_前戳的不会作为关键字
导入时的参数,对应类的初始化方法
如果类和模块文件同名,声明的时候就可以省略后面的类名
第13、14节项目目录和用例
RF用例的执行
robot framework 的命令格式
robot options data #执行的目录或套件文件
options 是RF命令的选项,可以为空
data 则是要执行的测试套件文件或目录,的路径,可以是绝对路径,也可以是相对路径
相对于当前shell终端的工作目录
robot test.robot
robot path/to/my_tests
robot c:\robot\test.robot
如果指定的是测试套件文件,则执行该文件中所有的测试用例
如果指定的是测试套件目录,则递归执行该目录下包含的所有子目录里面所有测试套件
文件里面的所有用例
可以指定多个要执行的测试套件文件,目录,甚至是 用通配符来表示多个测试
,如下所示
robot my_tests.robot you.robot
robot --name examle path/to/my_tests_*.robot
多个测试数据的情况本次测试的名称就是它们的名字相加
my_tests &you test
用–name选项来指定测试名称,像上面第二行所示
robot --pythonpath . --name 回归测试 tc
根据名称选择测试用例
我们可以通过–test --suite 来指定执行哪些用例或者套件
而且还支持用通配符的方式
例如:
robot --python . --test 添加课程1 web
robot --python . --suite 老师管理 web
robot --python . --test 添加课程1 --test 添加老师1 web
如果从测试库中导出的用例,可以直接根据编号进行执行
例如编号是:
tc001
tc002
robot --pythonpath . --testtc001 --testtc002
如果执行用例特别长,可以用参数文件的方式解决这个问题
–pythonpath .
–name 添加老师1
web
然后在文件中执行
robot -A NAME
初始化清除工作,包括关键字的实现,在python代码中实现
from robot.api import logger
class WebOpAdmin():
ROBOT_LIBRARY_SCOPE = ‘GLOBAL’
def __init__(self):
logger.console('***** OpAdmin init')
def op1(self):
print('ok')
第15节、16节作业讲解与用例标签
例子:
*** Settings ***
Force Tags 登录 冒烟测试 #该套件所有测试用例都具有了该tag
Default Tags notag #该套件里没有【tags】 设置的测试用例都具有了该tag
测试目录里面有__init__.robot 不支持default Tags
*** Test Cases ***
用例30001
[Tags] 正确用户名 正确密码
log to console 用例30001主体部分
用例30002
[Tags] 正确用户名 正确密码
log to console 用例30002主体部分
根据标签选择测试用例
#执行包含标签’foo’的用例
–include foo
例子:robot --include web测试 “webtest” #引号中是数据源
#执行不包含标签’foo’ 的用例
–exclude foo
#执行同时包含 标签 ‘one’,'web test’的用例
–include oneAND"web test" #AND 要大写 标签有空格,要加引号
#执行包含 标签’one’ 或者’two’ 的用例
–include oneORtwo
#执行包含 标签’ one’ 但是不包含标签’two’的用例
–include oneNOTtwo
例子:robot – include notag “webtest” #执行标签为 notag 的用例
#执行标签格式为ww 的用例
–include ww
执行所有的用例
例子:robot --include * “webtest”
执定关键测试用例
如果本次测试中有关键测试用例没有通过,那么整个测试就被视为不通过,反之,整个测试就视为通过
缺省情况下,RF执行测试时,每个测试用例都被视为关键测试用例
我们可以通过命令参数 – critical (-c) 和 --noncritical (-n) 后面加tag名来指定测试用例是否为关键测试用例
–critical regression 指定只有具有 regression 标签的用例才是关键用例
–noncritical not_ready 指定不具有not_ready 标签的用例是关键用例,其他用例都不是关键用例
–critical ok* --noncritical tbd* 指定具有以ok开头的标签 且没有以tbd开头的标签的用例都是关键用例
,其他用例都不是关键用例
通常我们可以在关键用例中打上标签,比如basic表示是关键用例
指定console 输入格式
让执行过程中更加的精简清晰
robot – quiet test.robot # 除了出错和警告信息,不输出 其他信息
robot --dotted tests.robot #执行用例用.表示通过的用例,F表示错误的用例
(不过很少用)
RF 总结:
提供套件和目录这种结构,结构清晰
初始化清除机制灵活,
选择用例执行灵活,可以根据标签和关键用例执行
比较详细的可视化的报告输出
为测试用例的开发者提供了清晰的关键字定义用例的模式
第1、2节项目实战
项目主要功能:
在线作业
同步课学习
统计分析
管理功能:
系统标签
资源管理
学校管理
API接口自动化
三个步骤,
分析需求文档,包括需求说明,接口文档
编写测试用例
执行测试,包括手动测试,自动化
选型:
框架robotframework
开发语言python
做项目的时候,构建一个自动化的目录结构
根据功能点和数据环境来构建
1、在写测试用例的,尽量把相同功能点的测试用例的编号放在一起,那么不同功能点之间应该预留一部分编号,以便为剩余用例预留编号空间。
2、进入测试单元(测试目录、文件、用例)的数据环境要与退出时的数据环境保持一致,所以测试套件如果有setup一定要有teardown
第一种方法:
在关键字表中设置一个全局变量
例子:
*** Keywords ***
suite setup action
${ret} add school class 1 1班 60
set global variable ${suite_g7c1_classid} &{ret}[id]
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup suite setup action #注意这个地方不要写错
Suite Teardown delete_school_class ${suite_g7c1_classid}
第二种方法:
首先在测试库中导入:
from robot.libraries.BuiltIn import BuiltIn
然后再指定的函数中增加如下代码:
例子:
def add_school_class(self,gradeid,name,studentlimit,idsavename=None):
payload = {
‘vcode’ : self.vcode,
‘action’ : ‘add’,
‘grade’ : int(gradeid),
‘name’ : name,
‘studentlimit’ : int(studentlimit),
}
response = requests.post(self.URL,data=payload)
bodyDict = response.json()
pprint (bodyDict,indent=2)
if idsavename:
BuiltIn().set_global_variable('${%s}'%idsavename,
bodyDict['id'])
return bodyDict
测试套件内的初始化文件中可以这样写:
*** Settings ***
Library pylib.SchoolClassLib
Suite Setup add school class 1 1班 60 suite_g7c1_classid #这个就是要传入的变量值,名字可以自定义命令
Suite Teardown delete_school_class ${suite_g7c1_classid} #这个要加{} 它指向的是一个字符串对象
说明:idsavename是参数名,为了让其他用例能够用这个全局变量,使用参数传入的方式
默认为空,可以 不传入,如果不为空就传入一个变量值,这个变量值将指向指定的对象,且是全局变量
这样,在套件文件中即可使用该全局变量。
robot截图方法:
from selenium import webdriver
from cfg import *
import time
from pprint import pprint
import selenium.webdriver.support.ui as ui
class WebOpLib:
ROBOT_LIBRARY_SCOPE = ‘GLOBAL’
def init(self):
self.num = 0
def open_browser(self):
self.wd = webdriver.Chrome()
self.wd.implicitly_wait(10)
def close_browser(self):
self.wd.quit()
def screenshot(self):
self.num +=1
self.wd.get_screenshot_as_file(f’D:/screenshot_{self.num}.png’)
print(f"HTML The screenshot of the failure is located click here")
用例中
写明:
RUN KEYWORDS run keyword if test failed screenshot