【Robot Framework 】项目实战汇总
写在前面
RF自动化的文章记录基本完成,建一个汇总目录,方便查看。
【Robot Framework 项目实战】汇总
∮【RF 项目实战 01】使用 RequestsLibrary 进行接口测试
∮【RF 项目实战 03】使用脚本自动生成统一格式的RF自动化用例
∮【RF 项目实战 04】基于录制生成RF关键字及基础自动化用例
脚本优化
上一篇博客我们编写了基于录制生成的RF自动化Demo用例,但是只是完全根据抓包数据构造了一条正常的测试用例,其实针对接口的参数校验这样的重复性比较强的测试,我们也可以把它们脚本化,参数化到RF文件中。
接口测试,基本参数校验范围
基本参数校验,是每次接口测试首要考虑的内容,这部分应当是测试工程师的基本能力。
- 可选与必选:
- 字段可选,传与不传时的区别
- 字段必选,必选参数缺失时返回什么错误,返回格式是否标准
- 空值:
- 空值时,返回什么结果。(如网络超时未返回,当成空值在处理还是默认值处理)
- 默认值:
- 是否有默认值,可选参数和必选参数是否有默认值
- 类型:
- int,区分32和64位,int类型时,传str时的错误展示
- string类型,
- float类型,往往在计算金额时,会用到浮点数
- 类型长度:
- 超过长度,接口请求是否出错,如果不出错,展示是否被截断
- 中文跨越边界时被截断的问题,如nickname是32字节,共16个中文,前15是中文,第16是英文,第17是中文,则多出一个字节,最后一个中文是否被截断显示为乱码
- 大小写:
- 是否大小写敏感,signkey,等内容,一般大小写敏感
- 安全过滤:
- <>是否被过滤掉,是否有直接存写到DB
- ' " 是否被转译或者使用防SQL注入的ORM组件
- 编码类型:
- utf-8,GBK,unicode
- 特殊字符(空格,换行等),emoji(4个字节),中文,拉丁文,日文等
具体实现
首先我们定义一批可能需要传递的参数,使用常量的方式存储。
PARAM_ERR = 10000
OK = 0
BOOL = True # False
INT = 10
NEG_INT = -1
ZERO = 0
BIG_INT = 99**5
NEG_FLOAT = -1.1
FLOAT = 0.99
EMPTY_STR = ""
INT_STR = "1111"
LETTERS_STR = "ABCabc"
SPACE_STR = " "
EMPTY_LIST = []
STR_LIST = ["a", "b"]
INT_LIST = [10, 20]
BOOL_LIST = [True, False]
MIX_LIST = ["a", True, 10, ["aa"], {"a": "aa"}]
EMPTY_DICT = {}
STR_DICT = {"a": "b"}
INT_DICT = {"d": 11}
BOOL_DICT = {"c": True}
MIX_DICT = {"b": "", "c": True, "d": 11, "e": {"f": [1, 2]}}
...
然后我们通过原始的请求参数,自己组装不同的请求参数:
def gen_req_data(sheet_obj):
str_params = sheet_obj.cell_value(1, 1)
str_method = sheet_obj.cell_value(1, 6)
temp_list = []
# print(f"str_params:{str_params}")
if not len(str_params):
return ""
try:
# 转化 json类型为Python标准类型
params = eval(str_params.replace("false", "False").replace("true", "True").replace("null", "None"))
if not len(params):
return ""
except Exception as f:
logger.warning("====================================================")
logger.error("=" + str(f))
logger.warning("====================================================")
params = ""
# 正常参数
temp_list.append(params)
# 添加异常参数
for k, v in params.items():
if isinstance(v, dict):
for i in [
BOOL,
NEG_FLOAT,
LETTERS_STR,
MIX_LIST,
ZERO,
MIX_DICT
]:
params = copy.deepcopy(params) # 深拷贝,字典存储的是内存地址
params[k] = i # doc
temp_list.append(params)
elif isinstance(v, list):
for i in [BOOL, NEG_FLOAT, LETTERS_STR, MIX_LIST, ZERO, MIX_DICT]:
params = copy.deepcopy(params)
params[k] = i
temp_list.append(params)
elif isinstance(v, str):
for i in [BOOL, NEG_FLOAT, EMPTY_STR, INT_STR, SPACE_STR, MIX_DICT, STR_LIST, EMPTY_DICT]:
params = copy.deepcopy(params)
params[k] = i
temp_list.append(params)
elif isinstance(v, int):
for i in [BOOL, NEG_FLOAT, INT_STR, INT_LIST, NEG_INT, ZERO, BIG_INT, NEG_FLOAT, FLOAT, EMPTY_DICT]:
params = copy.deepcopy(params)
params[k] = i
temp_list.append(params)
elif isinstance(v, bool):
for i in [True, False, ZERO, FLOAT, NEG_INT, INT_STR, INT_LIST, STR_DICT]:
params = copy.deepcopy(params)
params[k] = i
temp_list.append(params)
return str_method, temp_list
最后,我们把不同的请求参数转化为RF测试用例需要的数据格式,最终生成对应的测试用例:
def gen_testcase(self, sheet_obj, target_robot_name, interface_name):
"""
:param sheet_obj:
:param target_robot_name:
:param interface_name:
:return:
"""
method, params_list = self.gen_req_data(sheet_obj)
with open(target_robot_name, 'a') as f:
for num, param in enumerate(params_list):
"""
待办:动态修改Documentation的信息,异常参数以tuple的形式存储Documentation,然后解析的时候参数化到文档中
"""
f.write(interface_name + f'.Demo_case{num}' + '\n')
f.write(' [Documentation] demo' + '\n')
f.write(' [Tags] ' + self.tag + '\n')
params = self._gen_param_data(method, param)
f.write(params)
if params:
f.write(' ${{Resp_data}} {}'.format(self.project_abbr) + interface_name + ' ${HOST} ' + "${param}")
else:
f.write(' # 未获取到请求参数数据 \n')
f.write(' ${{Resp_data}} {}'.format(self.project_abbr) + interface_name + ' ${HOST} ' + "${EMPTY}")
f.write('\n')
f.write(' Log ${Resp_data.text}' + '\n')
# 第一条用例正常断言,其他用例标记为失败用例
if num == 0:
f.write(' Should Be Equal As Strings ${Resp_data.status_code} 200' + '\n')
f.write(' ${resp_json} to json ${Resp_data.text}' + '\n')
f.write(self.gen_exp_data(sheet_obj))
else:
f.write(f' Should Be Equal As Strings ${{Resp_data.status_code}} {self.error_status_code}' + '\n')
f.write(' ${resp_json} to json ${Resp_data.text}' + '\n')
f.write(self._format_exp_data(self.param_error_json)) # param_error_json 接口异常返回内容中的公共部分,比如code, result
f.write('\n')
logger.info("Demo case保存于:" + target_robot_name)
注:⚠️ 部分依赖代码在上一篇文章中可以找到。
总结
通过抓包,我们获取了原始数据,然后根据抽象异常参数传递校验的方式,把接口测试异常用例抽取了出来,这个不管是在手工测试过程中,还是在自动化过程中都非常的有用,能节省大量的人力成本。
当然这个方式也有一定的局限性,需要整个团队来配置,比如脚本中使用到的param_error_json
就是因为博主所在项目组有比较规范的接口返回定义才能做这样的统一断言。
【Robot Framework 】项目实战汇总的更多相关文章
- 【Robot Framework 项目实战 01】使用 RequestsLibrary 进行接口测试
写在前面 本文我们一起来学习如何使用Robot Framework 的RequestsLibrary库,涉及POST.GET接口测试,RF用例分层封装设计等内容. 接口 接口测试是我们最常见的测试类型 ...
- 【Robot Framework 项目实战 00】环境搭建
前言 我们公司在推广RF这个框架做后端接口测试,力求让同事们能更快的完成服务端需求的自动化,作为主导者之一,决定分享一些经验,方便后来者. 我会从安装部署.Request.selenium.自定义框架 ...
- 【Robot Framework 项目实战 02】SeleniumLibrary Web UI 自动化
前言 SeleniumLibrary 是针对 Robot Framework 开发的 Selenium 库.它也 Robot Framework 下面最流程的库之一.主要用于编写 Web UI 自动化 ...
- 【Robot Framework 项目实战 03】使用脚本自动生成统一格式的RF自动化用例
背景 虽然大家都已经使用了统一的关键字,但是在检查了一些测试用例之后,还是发现因为大家对RF的熟悉程度不一导致的测试用例颗粒度差异很大的情况:而且在手动方式转化测试用例过程中,有不少工作是完全重复的且 ...
- 【Robot Framework 项目实战 02】使用脚本生成统一格式的RF关键字
背景 在微服务化的调用环境下,测试数据及接口依赖的维护是一个问题,因为依赖的接口和数据可能不在同一个服务下,而这相关的多个服务往往是不同人员来测试的. 因此为了节省沟通成本,避免关键字的重复冗余.所以 ...
- 【Robot Framework 项目实战 04】基于录制,生成RF关键字及 自动化用例
背景 因为服务的迁移,Jira版本的更新,很多接口文档的维护变少,导致想要编写部分服务的自动化测试变得尤为麻烦,很多服务,尤其是客户端接口需要通过抓包的方式查询参数来编写自动化用例,但是过程中手工重复 ...
- Robot Framework 项目搭建
首先新建一个项目“RobotDemo".项目Type一般选择“Directory”形式. 项目第一层可以放3种文件:Test Suite.Directory 和 Resource File. ...
- Robot Framework 学习资源汇总
学习网站 http://robotframework.org/ http://www.testtao.cn/?cat=43 https://www.jianshu.com/c/483e8ffcbc79 ...
- 自动化测试框架Cucumber和Robot Framework的实战对比
自动化测试框架Cucumber和RobotFramework的实战对比 一.摘要 自动化测试可以快速自动完成大量测试用例,节约巨大的人工测试成本:同时它需要拥有专业开发技能的人才能完成开发,且需要大量 ...
随机推荐
- Python考试_第一次
python基础数据类型考试题 考试时间:两个半小时 满分100分(80分以上包含80分及格) 一,基础题. 1. 简述变量命名规范(3分) 答:(1) 变量为数字,字母以及下划线的任意组合,且不能以 ...
- 使用ctypes调用系统C API函数需要注意的问题,函数参数中有指针或结构体的情况下最好不要修改argtypes
有人向我反应,在代码里同时用我的python模块uiautomation和其它另一个模块后,脚本运行时会报错,但单独使用任意一个模块时都是正常的,没有错误.issue链接 我用一个例子来演示下这个问题 ...
- printPreviewControl1怎么刷新文档
printPreviewControl1.InvalidatePreview(); 调用printPreviewControl1控件的 InvalidatePreview() 这个方法即可.
- SAP Marketing Cloud里的contact main facet是什么意思
界面如下: Basically, contact data for SAP Hybris Marketing can be loaded from various sources, such as a ...
- Ubuntu 其他命令
其他命令 目标 查找文件 find 软链接 ln 打包和压缩 tar 软件安装 apt-get 01. 查找文件 find 命令功能非常强大,通常用来在 特定的目录下 搜索 符合条件的文件 序号 命令 ...
- 用cef Python打造自己的浏览器
背景 项目需要做一个客户端的壳,内置浏览器,访问指定 的url 采用技术 python3.5 cefpython https://github.com/cztomczak/cefpython#inst ...
- myeclipse 添加反编译插件
文件下载地址: 链接: https://pan.baidu.com/s/1th2goaA2aS45kO84dX1Bdg 密码: g1fu 先关闭myeclipse1.下载jad1.5.8g 下载后解压 ...
- 深度学习之卷积神经网络CNN及tensorflow代码实例
深度学习之卷积神经网络CNN及tensorflow代码实例 什么是卷积? 卷积的定义 从数学上讲,卷积就是一种运算,是我们学习高等数学之后,新接触的一种运算,因为涉及到积分.级数,所以看起来觉得很复杂 ...
- FTP下载文件和操作系统的关系
标题不知道该怎么写了. 最近调试AGPS,嵌入式设备需要从FTP服务器上下载星历数据,星历数据是二进制数据.嵌入式设备下载完数据后和原始数据对比,发现数据量变大了(但是通过pc端的FTP软件下载下来的 ...
- sqlmap中文帮助文档
Options(选项): -h,--help 显示基本帮助消息并退出 -hh 显示高级帮助消息并退出 --version ...