【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的实战对比 一.摘要 自动化测试可以快速自动完成大量测试用例,节约巨大的人工测试成本:同时它需要拥有专业开发技能的人才能完成开发,且需要大量 ...
随机推荐
- 11. Java方法的定义与使用
1.1方法的定义 方法是一段可以被重复调用的代码块. 方法的声明: public static 方法返回值 方法名称 ([参数类型 变量...]) 方法体代码: [return 返回值]: 当方法以v ...
- SQL Server注入
1.利用错误消息提取信息 1.1 枚举当前表与列 --' 抛出错误:选择列表中的列 'users.id' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中. 发现表名为 'users',存 ...
- R语言学习笔记:glue包实现变量传参
glue包介绍 glue包可用于自定义变量,然后通过传参的方式,对字符串部分内容进行自适应修改. 例如:可将日期赋值为:date = as.Date("2019-12-05"),然 ...
- jQuery异步请求ajax()之complete参数详解
请求完成后回调函数 (请求success 和 error之后均调用).这个回调函数得到2个参数:XMLHTTPRequest) 对象和一个描述请求状态的字符串("success", ...
- 线程池工具ThreadPoolExecutor
JDK1.5中引入了强大的concurrent包,其中最常用的莫过了线程池的实现ThreadPoolExecutor,它给我们带来了极大的方便,但同时,对于该线程池不恰当的设置也可能使其效率并不能达到 ...
- Invariant Violation: requireNativeComponent: "RNCWKWebView" was not found in the UIManager.
react-native 0.60以上版本安装第三方库的时候会autolink 出现这个问题是 我安装 react-native-webview 之后运行 ios出现的,这是因为ios 没有自动安 ...
- umi model 注册
model 分两类,一是全局 model,二是页面 model.全局 model 存于 /src/models/ 目录,所有页面都可引用:页面 model 不能被其他页面所引用. 规则如下: src/ ...
- 用pythoninstall cefpython打包exe,制作自己的浏览器
cefpython浏览器 介绍 用pythoninstall cefpython打包exe,制作自己的浏览器, 软件架构 PyInstaller: 3.4 Python: 3.5.4 Platform ...
- smart_ptr之shared_ptr
智能指针的概念 c++11标准和boost都提供了智能指针的功能.智能指针是普通指针的封装,智能指针是一个对象,对象里面包含了原生指针.可以使用智能指针对象的get()方法可获得封装在里面的原生指针. ...
- 【问题】This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
转载请注明出处:https://www.cnblogs.com/kelamoyujuzhen/p/9087725.html 这类问题归根到底就是软件源问题,Linux下安装软件不像windows.L ...