30行左右代码实现一个类似httprunner的接口框架

框架的最终归宿往往是领域语言+模板解析。
首先先约定一种所要执行操作的表述格式。然后通过模板解析将描述语言转化为代码进行执行。例如,我们可以使用以下yaml文件描述多个步骤并且需要关联的接口:
apis.yaml:

- name: 获取百度token接口 # 接口名称
  request:  # 请求报文
    url: https://aip.baidubce.com/oauth/2.0/token
    method: get
    params:
      grant_type: client_credentials
      client_id: kPoFYw85FXsnojsy5bB9hu6x
      client_secret: l7SuGBkDQHkjiTPU3m6NaNddD6SCvDMC
  extract:  # 提取变量, 字典格式
    token:  RESPONSE.json()['access_token']  # RESPONSE系统变量,代表响应对象

- name: 百度ORC接口  # 第二个接口
  request:
    url: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=${token}  # 使用变量
    method: post
    data:  # 请求体(表单格式)
      url: http://upload-images.jianshu.io/upload_images/7575721-40c847532432e852.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
  verify:  # 断言, 列表格式
    - RESPONSE.json()['words_result_num'] == 6

其中,name为该接口或步骤的名称描述,request段是接口的信息,对应requests.request()的每一个参数,urlmethod是必要参数,params,headers,cookies,data, json,files,timeout等,并使用对应格式。extract用于提取值, token: RESPONSE.json()['access_token'] ,表示提取该接口响应字典中的access_token字段的值保存为名为token的变量。
在第二个接口的url中通过使用${token},引用该变量。
verify段类似与extract, 计算表达式的值,通过结果的True/False判断该条断言是否通过。

上面我们定义了一套接口关联的描述及规则,下面我们要对我们的规则进行解析,并加载运行,主要分为以下几步:

  1. 读取yaml文件并使用yaml.safe_load(f)转为列表/字典
  2. 遍历列表,每个列表项是一个接口
  3. 读取当前列表项(接口)的request段信息,处理${变量}
    1. 将request段(字典格式)重新转会yaml字符串
    2. 如果包含$使用string.Template('字符串').safe_subtitute(locals()),从locals()当前所有局部变量中找到$表示的同名变量,如token,并替换。
    3. 重新将替换后变量的字符串转化为字典
  4. 字典拆包,发送request请求
  5. 如果请求中有extract字段,使用eval()计算表达式的值并保存到局部变量locals()中。
  6. 如果请求中有verify字段,使用eval()计算表达式的值,并判断真假。

实现代码:

需要安装pyyaml: pip install pyyaml

apis_parser.py

import yaml
import requests
from string import Template

with open('apis.yaml', encoding='utf-8') as f:
    apis = yaml.safe_load(f)

for api in apis:
    print("处理请求:", api.get('name'))
    request = api.get('request', {})  # 请求报文,默认值为{}
    # 处理参数化请求中的${变量}
    request_str = yaml.dump(request)  # 先转为字符串
    if '$' in request_str:
        request_str = Template(request_str).safe_substitute(locals())  # 替换${变量}为局部变量中的同名变量
        request = yaml.safe_load(request_str)  # 重新转为字典
    # 发送请求
    res = requests.request(**request)  # 字典解包,发送接口
    # 提取变量
    extract = api.get('extract')
    if extract is not None:  # 如果存在extract
        for key, value in extract.items():
            # 计算value表达式,可使用的全局变量为空,可使用的局部变量为RESPONSE(响应对象)
            # 保存变量结果到局部变量中
            print("提取变量:", key, value)
            locals()[key] = eval(value, {}, {'RESPONSE': res})  
    # 处理断言
    verify = api.get('verify')
    if verify is not None:
        for line in verify:
            result = eval(line, {}, {'RESPONSE': res}) # 计算断言表达式,True代表成功,False代表失败
            print("断言:", line, "结果:", "PASS" if result else "FAIL") 

执行结果:

处理请求: 获取百度token接口
提取变量: token RESPONSE.json()['access_token']
处理请求: 百度ORC接口
断言: RESPONSE.json()['words_result_num'] == 6 结果: PASS
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容

  • 框架的最终归宿往往是领域语言+模板解析。 首先先约定一种所要执行操作的表述格式。然后通过模板解析将描述语言转化为代...
    琉璃_233a阅读 102评论 0 0
  • 前言 之前写过一个简单的httprunner的实现:30行左右代码实现一个类似httprunner的接口框架使用P...
    韩志超阅读 960评论 0 2
  • 实现代码: 需要安装pyyaml: pip install pyyaml apis_parser.py impor...
    琉璃_233a阅读 115评论 0 0
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,093评论 1 23
  • 生在这样的年纪,承受着这个年纪拥有的孤独。上不能与长辈喝酒划拳,下不能和小孩子奔跑撒野。 或者其实是,只有我自己仍...
    PoorJoy阅读 227评论 0 1