背景
公司上线了信创版本的新项目,迭代频繁,需要能够支持对基础功能的快速回归,考虑到UI测试投入成本大收益慢且不能实现快速回归,选择了接口自动化测试。调研了市场上的自动化测试工具,基于公司项目的特点,最终选择了灵活性较大的httprunner框架。
基于系统请求特点改造适配
接口测试遇到的问题:
1、系统请求的请求头中需要包含token,用例步骤中需要自动带上token
2、系统请求的参数content-type都是application/x-www-form-urlencoded; charset=UTF-8,传入到后端的中文都是经过了url编码后的,如果在用例编写过程中也直接用编码后的参数,就很难做到可参数化,且用例的参数无法直观看到是什么参数。
解决方法是定义一个装饰器pre_decorator,作用于类上面。pre_decorator实现注入base_url,构造带有token的请求头,从参数excel文件读取参数,自动替换测试类的参数和对测试步骤中的请求参数进行url编码
```java
```java
```python
def pre_decorator(cls):
pre_handle(cls.config, cls.config.path, cls.teststeps)
return cls
在类加载时候返回经过pre_handle处理后返回新的类,pre_handle
def pre_handle(config=Config, file_path='', teststeps=[Step]):
config.base_url('${ENV(base_url)}')
config.verify(False)
# 构造请求头
if teststeps:
headers = {
"User-Agent": get_user_agent(),
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Authentication": get_accessToken()
}
for step in teststeps:
if step.request.headers:
headers.update(step.request.headers)
step.request.headers.update(headers)
else:
step.request.headers.update(headers)
# 填充参数
index = str.index(file_path, 'testcases')
file_path = file_path[index:].replace('\\', '.')
if parameters == {}:
init_parameters()
config_variables = {}
if file_path in parameters:
if parameters[file_path] and str(parameters[file_path]) != 'nan':
config_variables = eval(parameters[file_path])
if config.struct().variables != None and len(config.struct().variables) > 0:
new_config_variables = copy.copy(config.struct().variables)
new_config_variables.update(config_variables)
config.variables(**new_config_variables)
else:
config.variables(**config_variables)
# 自动替换参数和编码参数
if teststeps:
for step in teststeps:
# 替换参数
data = step.request.data
if data != None:
for param in config.struct().variables:
data = re.sub(f"{param}=(?!\\$).+?&", f"{param}= {config.struct().variables[param]}&", data)
data = re.sub(f'"{param}":"(?!\\$)(?!\\[).+?"', f'"{param}":"{config.struct().variables[param]}"',
data)
data = re.sub(f'\'{param}\':.+?\'(?!\\$)(?!\\[).+?\'',
f'\'{param}\': \'{config.struct().variables[param]}\'', data)
step.request.data = data
if 'Content-Type' not in step.request.headers:
step.request.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
# 编码参数
if 'application/x-www-form-urlencoded; charset=UTF-8' in step.request.headers["Content-Type"] and type(
data) == str and '${' not in data:
step.request.data = parse.quote(step.request.data, safe="=,&, 00:00:00,00:00:00")
elif 'application/x-www-form-urlencoded' in step.request.headers["Content-Type"] and type(data) == str:
step.struct().setup_hooks.append("${encode($request)}")
用例编写和运行
开发的小工具实现了可以快速将请求转换为步骤,请求参数做了url反编码,可以快速编写用例,开发了用例启用功能,选择需要跑的用例,点击运行测试用例即可一键执行测试用例,执行完后自动打开对应的allure报告,实现快速回归。