说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/104264681
文章目录
四、创建 Robot Framework 测试
5.发送请求与处理响应
5.3 处理响应数据
5.3.1 获得响应正文
-
获得响应正文
✔ ${json 变量} to json ${响应结果.content} pretty_print=True
★ 美化 json 显示
■ pretty_print=True
✔ 获取 json 中的的项
★ ${变量} get from dictionary ${json 变量} 字典关键字
■ get from dictionary 表示根据字典关键值取值
■ to json 是不能使用 pretty_print=True -
将结果转换为json格式数据
-
运行后,查看响应数据,此时的响应数据是美化的
-
现在通过get from dictionary来获取json格式结果数据中的status以及desc键下的数据,需要注意的是此时对于响应正文结果不能使用pretty_print=True进行修饰美化数据
-
运行后,成功提取出json数据中的status以及desc关键字数据
5.3.2 获得响应状态码
- 获得响应状态码
✔ ${响应结果.status_code}
5.3.3 获得响应cookies
-
获得响应 cookies
✔ ${响应结果.cookies}
★ 返回 RequestsCookiesJar 对象
★ 结果是字典形式,Cookie 与 for 间的内容为 cookies 参数与值
✔ ${响应结果.cookies}[参数名]
★ 获得某个 cookies 参数的值
★ 参数名区分大小写
★ 参数无需引号
✔ ${cookie} get from dictionary ${响应结果.cookies} cookies 参数名
★ 将取到的 cookies 存到自定义 cookie 变量 -
注释掉获取status、desc以及json数据的脚本,直接log删除结果数据中的cookies
-
运行脚本后,返回的数据为对象,说明没有获取到cookie,那么原有是发送请求时cookie的值为None
-
为了更好的演示,所以需要换一个存在cookie的接口,在webtours登录时需要使用cookie,所以这里博主使用badboy录制webtours登录脚本,使用jmeter打开,可以看到如下url连接存在cookie数据
-
查看该请求详情,是否存在参数以及请求方式
-
然后回到robot中,编写webtours下的login用例
-
运行脚本,成功打印出cookie数据
-
取出名为MSO的cookie的值
-
还可以将获取到的cookies数据转存到变量中
5.3.4 获得响应头
-
获得响应头
✔ ${响应结果.headers}
★ 也可在${响应结果.headers}中取到 cookies
★ ${cookie} get from dictionary ${响应结果.headers} Set-cookie
■ Set-cookie 一般是关键字
★ ${cookie} fetch from left ${cookie} 右边的分割字符串
■ 根据指定字符串拆分,然后去左边的串,结果重新存储
■ 需要导入 String 包 -
获取响应结果中的headers
-
对比在jmeter中如下响应头
-
将响应数据拷贝到记事本中,进行查看
-
现在通过get from dictionary 取出Set-cookie的值
-
运行结果成功提取出Set-cookie的数据
-
对Set-cookie的值进行提取出MSO=SID&1581569877,使用fetch from right取GMT,右边的字符串,然后再对结果使用fetch from left取; path=/左边字符串,得到的就是想要的字符串
-
运行脚本,成功提取出我们想要的数据
5.3.5 发送cookies数据
- 发送 cookies 数据
${响应结果} get request 会话名 /路径?参数=值&cookie 参数名=值 - 在jmeter中如下url则会向服务器发送cookies数据
- 在robot中编写脚本,向该url发送get请求并传递参数以及cookies值
- 运行脚本,成功打印出响应正文数据,返回会话值
5.4 正则表达式查找数据
-
${结果} get regexp matches 源字符串 (?i)正则表达式 1
✔ 需要导入 String 包
✔ 源字符串必须是字符串格式
★ 如${响应结果.text}
✔ (?i)
★ 忽略大小写
✔ 正则表达式需要使用( )包含
★ 一对( )一个模式
✔ 1 表示匹配第几个模式,且只输出匹配到的字符串
✔ 结果是列表形式
✔ ${结果}[0]
★ 获得结果列表中的第 1 个
★ 结果是字符串形式 -
首先通过jmeter来查看webtours登录url的请求详情参数
-
在robot中编写用例脚本,暂不填写请求参数userSession
-
运行用例,发现响应正文数据,不是登录成功的(因为没有发送userSession)
-
现在通过正则匹配出之前获取的nav.pl链接响应数据中的userSession的值,需要注意的是不能从响应正文content中获取,要从text文本数据中进行正则匹配,因为content结果是二进制数据
-
运行脚本,成功提取出userSession的值,这个值存放在列表中
-
接下来要只获取这个值,那么就很简单,取出列表第一个元素即可,在以上脚本加上${session}[0]即可,运行脚本成功取出这个值
5.5 变量转存
-
${结果} convert to string 源变量
✔ 将变量转换为字符串
✔ 变量严格区分大小写 -
将获取到的userSession的值转存到session变量中
-
运行脚本,也是没有问题的
-
接下来取消之前注释掉的登录请求,在datas变量中添加userSession会话值参数
-
运行脚本,成功登录,此时的title显示为webtours
6.断言
6.1 Should Be Equal
- ${变量} Should Be Equal 变量 1 变量 2 断言失败消息 ignore_case=True
✔ 判断是否相等,变量 1 相当于实际结果,变量 2 相当于预期结果
✔ 返回值接收变量可以省略
★ 断言成功时返回 None,否则无返回值
★ 输出日志
■ 断言失败信息+变量 1!=变量 2
✔ ignore_case=True
★ 表示忽略大小写 - 切换到天气接口测试用例中,断言响应正文json数据中的status状态码是否为1000,如果断言失败则提示状态码错误,需要注意的是获取的status状态码1000为int类型,所以需要提前转换
- 运行脚本,断言成功,没有打印出状态码错误
- 那么如果将断言数据改为10001,则运行脚本,提示状态码错误断言失败
- 因为当状态码断言成功时赋值给变量assert,其结果没None,所以由此可以进行if判断
- 运行脚本,成功打印出断言状态码成功
6.2 Should Contain
-
${变量}Should Contain item1 item2 断言失败消息 ignore_case=True
✔ 断言 item1 中是否包含 item2
★ 通过时返回 None,否则无返回值
★ 失败时,输出断言失败消息与失败原因 -
切换到webtours登录用例,使用Should Contain断言响应文本数据中是否包含Web Tours
-
运行脚本,显示登录成功
-
将断言数据,变为小写的web tours,运行脚本,显示登录失败
-
如果想要忽略大小写,则在后面加上ignore_case=True
-
运行脚本,也是没有任何问题的
6.3 Should Match Regexp
-
${变量} Should Match Regexp 变量 1 (?i)left 正则表达式模式 right 断言失败消息
✔ 搜索变量 1 中匹配正则表达式的字符串
★ (?i)表示忽略大小写
★ left 表示模式左边的字符串,right 表示模式右边的字符串
★ 模式一般需要使用( )包含,一对( )是一个模式
✔ 若匹配,则返回列表,第一个元素是原数据,后面的元素是匹配到的数据
★ 若不匹配,则输出断言失败消息+失败原因
✔ ${变量} Should Match Regexp 变量 1 \d{6}
★ 搜索变量 1 中一开始的连续 6 个数字字符串 -
切换到test用例,首先设置变量s的值,然后使用正则断言匹配出存在的数据
-
运行脚本,查看结果,成功
-
对脚本进行优化,根据以上正则匹配的结果说明正则匹配成功得到一个列表数据,那么可以通过len方法获取结果的长度,如果大于0则表示成功,那么就打印出这个列表中的第二个元素
-
运行脚本,成功提取出正则匹配出的列表数据中的值
7.参数化
7.1 使用列表参数化
-
获得省或直辖市的名称
✔ ws.webxml.com.cn/WebServices/WeatherWS.asmx/getRegionProvince -
对省或直辖市接口,发送请求
-
运行脚本,查看响应文本数据,成功获得省
-
那么而现在,则需要对以上数据使用正则进行提取出省
-
运行结果,成功打印出省份列表数据
-
查看列表的长度来判断是否数据完成
-
显示没有任何问题
-
接下来这是,取消之前发送天气请求的脚本,然后使用for循环遍历上面获取到的sheng列表数据,需要注意的是在for循环遍历列表数据时应该使用@而不是$
-
运行脚本,显示断言失败,从测试结果中可以看到city为黑龙江,说明for循环遍历出来的city变量的数据是没有问题的,断言失败也是正常的,原因是在之前的jmter中接口测试天气就已说明有很大一部分省份是查询不到天气数据的
-
断言失败继续运行
✔ ${断言的结果变量} run keyword and continue on failure 断言 -
从以上可以看出当遍历第一个黑龙江时,断言失败后,则不再继续执行下去,如想继续执行下去,则需要在断言结果变量后面添加如下语句
-
运行脚本,成功完成所有城市的变量
-
对脚本进行优化,设置断言失败打印出城市city
-
运行脚本,查看断言失败结果,一目了然
7.2 使用文件数据参数化
- 首先在桌面创建一个users.txt文本,存放webtours用户名和密码,这里博主为了试错,将cdtaogang2的密码设置为错误密码
- 创建模块,至少定义函数,建议使用参数和返回值。
- 将 py 文件(即自定义库)拷贝到 Python\Lib\site-packages 下,在 RF 用导入 Library的方式导入。
- 回到用例中,因为已经导入了readfile模块,所以直接调用rf方法,然后传递filename参数
- 运行脚本,测试成功打印出users.txt中的用户数据
- 使用for循环遍历出每个列表中的第一个和第二个元素,第一个为用户名第二个为密码
- 运行后,成功取出用户名密码
- 替换脚本中的用户名和密码进行参数化,修改登录检查点数据
- 运行脚本,在遍历第一个用户名密码打印出登录成功,第二则提示登录失败,然后第三个没有执行
- 需要在脚本断言结果后面,添加断言失败继续执行语句run keyword and continue on failure,运行脚本,第三个用户显示登录成功
8.命令行运行测试
-
查找\Python\Scripts 中是否有 pybot.bat,如果没有,自行创建,输入: @Echo off python -m robot.run %*
-
运行测试
✔ pybot test.robot
★ 运行指定文件
✔ pybot *.robot
★ 运行当前目录下以.robot 为后缀名的测试文件
✔ pybot test_a
★ 运行当前 test_a 目录下的所有用例
✔ pybot ./
★ 运行当前目录下的所有的测试文件 -
为了方便测试,博主在Test测试套件下,再创建了2个用例
-
只运行桌面接口测试项目目录下的test.robot测试套件
-
现在运行所有的robot文件,也就是所有的测试套件,提示如下
-
删除__init__.robot初始化文件,再次运行,执行所有的测试套件成功
-
如果不删除__init__.robot初始化文件,可以直接运行接口测试目录即可,不需要在后面添加*.robot