网站设计专业,网站ie兼容性差,整站优化关键词排名,网站 seo优化接口自动化非常简单#xff0c;大致分为以下几步#xff1a;
准备入参调用接口拿到2中response#xff0c;继续组装入参#xff0c;调用下一个接口重复步骤3校验结果是否符合预期
一个优秀接口自动化框架的特点#xff1a;
【编码门槛低】#xff0c;又【能让新手学到…接口自动化非常简单大致分为以下几步
准备入参调用接口拿到2中response继续组装入参调用下一个接口重复步骤3校验结果是否符合预期
一个优秀接口自动化框架的特点
【编码门槛低】又【能让新手学到技术】【低调试门槛】【优秀的可读性】【很好的可维护性】能很【方便多人协同】以便【自动化代码能不断积累】形成规模效应且【自动化case覆盖率可量化】有失败重试机制克服环境的不稳定【清晰的测试报告】能【低成本且灵活地触发】指定环境、指定时间、指定范围
综上我们需要搭建一个同时满足以上特点的轻量级接口自动化框架
首先管理接口 达成【编码门槛低】【方便多人协同】【优秀的可读性】【很好的可维护性】
被测接口单独管理目录结构和和开发使用的yapi保持一致统一放置在仓库下“接口管理”目录中如下 每个接口使用yaml文件管理如下且使用中文命名增加可读性。 method: post
host: ${host}
url: /copy/trading/v1/follower/edit
headers:{token: 799b72f3f94973f5a54a54204eac96a1aa94cd5d365245929098e921b2ddc154}
body:{followType: 1,traderUid: 102806,margin: 100,followAmount: 1000,stopLossRation: null,positionMode: 1,positionModeConfig: 0,leverModeConfig: 0,leverage: 1,marginModeConfig: 0,marginMode: 0,positionRisk: null,slippage: 0.006,}
response:code: # 响应码0 成功msg: # 返回描述code为0时返回成功data: # 响应数据 调用接口时默认用yaml文件中的参数剔除responseresponse只做示例用如需替换会在调用过程中标记具体需要替换的key value即可如下方便快捷 r.invoke_api(更新用户配置.yaml, headers{token: trader_son_token}, body{positionMode: 1})
其次编写代码调用接口 达成【编码门槛低】【优秀的可读性】【低调试门槛】【清晰的测试报告】
封装requests包使用requests.session()根据上述接口文档调用get或post方法且使用allure将入参和返回都放置到测试报告里面且此块代码无需实际接口测试同学关注。【能让新手学到技术】 class RequestUtil:def invoke_api(self, api, headersNone, bodyNone):解析需要调用的接口并且进行参数替换基础断言等:param api: 需要调用的接口:param header: 需要传入的请求头:param body: 需要传入的请求体:return: 返回接口响应的结果api_name apiparam YamlUtil.parse_api(api_name)if headers is not None:for key in headers:param[headers][key] headers[key]if body is not None:for key in body:param[body][key] body[key]params self.replace_value(param)with allure.step(f步骤{api_name}):response self.send_request(params)if self.run_mode 1:print()print(f调用接口{api_name})print(params)print(response)return responseelse:return responsedef send_request(self, *args):发起接口请求:param args: 接口请求的参数:return: 接口返回的数据method args[0][method].lower()ip self.replace_value(args[0][host])url ip args[0][url]headers args[0][headers]body args[0][body]data bodyif method get:res self.sess.get(url, paramsdata, headersheaders)elif method post:if files in args:files args[0][files]file_path os.path.join(YamlUtil.data_file_path, files)with open(file_path, rb) as file:files {file: (image.jpg, file)}res self.sess.post(url, filesfiles, headersheaders)res self.sess.post(url, jsondata, headersheaders)else:print(请求方式错误)try:res res.json()with allure.step(fURL{url}):...with allure.step(fMethod{method}):...with allure.step(fHeaders{json.dumps(headers)}):...with allure.step(fBody{json.dumps(data, ensure_asciiFalse)}):...with allure.step(fResponse{json.dumps(res, ensure_asciiFalse)}):return resexcept Exception as e:print(该接口返回的结果不是json数据)res res.textwith allure.step(fURL{url}):...with allure.step(fMethod{method}):...with allure.step(fHeaders{json.dumps(headers)}):...with allure.step(fBody{json.dumps(data, ensure_asciiFalse)}):...with allure.step(fResponse{json.dumps(res, ensure_asciiFalse)}):return res 通过pytest的fixture装饰器将RequestUtil注入进去每个测试用例里面去 pytest.fixture(scopesession)
def r():return RequestUtil()测试编码同学只需要使用方法即可完成接口调用和response获取接口百度.yaml method: post
host: https://ug.baidu.com
url: /mcp/pc/pcsearch
headers:{}
body:{errno: 0,errmsg: ok,data: {log_id: 1652589279,action_rule: {pos_1: [],pos_2: [],pos_3: []}}} 事实上测试代码只有这么点【编码门槛低】只需要能看懂接口文档和http的基本知识以及知道Python的字典和assert便可轻松完成编码 def test_百度(r):#其中 r为fixture装饰器通过conftest.py注入进去resdic r.invoke_api(百度.yaml,headers{},body{})assert resdic[errmsg] ok
assert resdic[data][log_id] 3277317105 不管成功失败测试报告都会打出每一次请求的入参和返回如下图都不用在IDE里面调试。【低调试门槛】【清晰的测试报告】另外数据驱动的case用如下的方式编写 import pytestpytest.mark.parametrize(emails,password,assert1, [(11111qq.com, Tset111, success),(22222qq.com, Tset222, fail),(33333qq.com, Tset333, error),
])
def test_注册用户(r, emails, password, assert1):response_info r.invoke_api(注册用户.yaml, body{emails: emails, password: password})assert response_info[data] assert1再次测试用例的组织和结构 达成【方便多人协同】【自动化代码能不断积累】【自动化case覆盖率可量化】
手工用例遵循实际的业务模块树形结构做较精细的模块拆分末级手工用例使用xmind管理作为用例树的末级标题上按如下打标哪些场景需要被覆盖目标已被覆盖进度功能覆盖率多少量化哪些地方还需要验证前端一目了然工时评估更透明 是否需要自动化是否已被自动化是否还需要验证前端自动化测试用例目录和手工用例目录保持一致每个自动化case一个.py文件自动化测试用例名与手工测试名保持一致。如此保障一一对应如若涉及一对多 如果涉及单接口的自动化测试用例名与手工用例末级目录一致如果涉及数据驱动的自动化测试用例名与手工用例末级目录一致通过以上措施很方便计算出自动化case覆盖率分子为已完成自动化case分母为达标为需要自动化的case数
再次通过配置文件和参数化运行 达成【低成本且灵活地触发】
yaml方式的配置文件 run_mode: 2 # 1调试模式/2正式模式
run_env: one # 运行脚本环境test:host: http://api.test.xyzdb:host:port:user:password:redis:host:password:testa:host: http://api.testa.xyzdb:host:port:user:password:redis:host:password:# 环境
one:# 接口地址host: # b连接信息db:host:port:user:password:# redis连接信息redis:host:password: main函数运行的时候拿到具体运行的环境信息读取对应的配置 import os
import pytest
from pytest_jsonreport.plugin import JSONReport
import argparsefrom Core.parse_yaml import YamlUtil
from Core.robot_utils import Robotdef main(env):YamlUtil.clear_env_yaml()if env.env is not None:e env.envdata {env: e}YamlUtil.write_env_yaml(data)current_path os.path.dirname(os.path.abspath(__file__))json_report_path os.path.join(current_path, report/json)html_report_path os.path.join(current_path, report/html)plugin JSONReport()pytest.main([自动化用例/百度搜索.py, --alluredir%s % json_report_path, --clean-alluredir], plugins[plugin])# 生成allure报告os.system(allure generate %s -o %s --clean % (json_report_path, html_report_path))os.system(allure open %s % html_report_path)if __name__ __main__:parser argparse.ArgumentParser()parser.add_argument(--env, help参数为需要执行的环境)args parser.parse_args()main(args) #在testa环境运行
python run.py --env testa