框架的最终归宿往往是领域语言+模板解析。

首先先约定一种所要执行操作的表述格式。然后通过模板解析将描述语言转化为代码进行执行。例如,我们可以使用以下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: //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

30行左右代码实现一个类似httprunner的接口框架的更多相关文章

  1. 30行JavaScript代码实现一个比特币量化策略

    精简极致的均线策略 30行打造一个正向收益系统 原帖地址:https://www.fmz.com/bbs-topic-new/262 没错!你听的没错是30行代码!仅仅30行小编我习惯先通篇来看看 代 ...

  2. 不到30行JS代码实现的Excel表格

    不到30行JS代码实现的Excel表格,jQuery并非不可替代 某国外程序员展示了一个由原生JS写成不依赖第三方库的,Excel表格应用,有以下特性: 由不足30行的原生JavaScript代码实现 ...

  3. 40多行python代码开发一个区块链。

    40多行python代码开发一个区块链?可信吗?我们将通过Python 2动手开发实现一个迷你区块链来帮你真正理解区块链技术的核心原理.python开发区块链的源代码保存在Github. 尽管有人认为 ...

  4. 30行Python代码实现人脸检测

    参考OpenCV自带的例子,30行Python代码实现人脸检测,不得不说,Python这个语言的优势太明显了,几乎把所有复杂的细节都屏蔽了,虽然效率较差,不过在调用OpenCV的模块时,因为模块都是C ...

  5. 8.如何自己设计一个类似 Dubbo 的 RPC 框架?

    作者:中华石杉 面试题 如何自己设计一个类似 Dubbo 的 RPC 框架? 面试官心理分析 说实话,就这问题,其实就跟问你如何自己设计一个 MQ 一样的道理,就考两个: 你有没有对某个 rpc 框架 ...

  6. Gora是一个类似Hibernate的ORM框架

    Gora是一个类似Hibernate的ORM框架,但是不只是支持关系数据库,更重要支持NoSQL之类大数据的存储. 支持NoSQL之类大数据的存储 Apache Gora是一个开源的ORM(Objec ...

  7. vnpy源码阅读学习(4):自己写一个类似vnpy的UI框架

    自己写一个类似vnpy的界面框架 概述 通过之前3次对vnpy的界面代码的研究,我们去模仿做一个vn.py的大框架.巩固一下PyQt5的学习. 这部分的代码相对来说没有难度和深度,基本上就是把PyQt ...

  8. 50行ruby代码开发一个区块链

    区块链是什么?作为一个Ruby开发者,理解区块链的最好办法,就是亲自动手实现一个.只需要50行Ruby代码你就能彻底理解区块链的核心原理! 区块链 = 区块组成的链表? blockchain.ruby ...

  9. 18 行 JS 代码编一个倒时器

    有时候在生活中,你需要一个JavaScript倒计时时钟,而不是一个末日装置设备.不管你是否有一次约会,销售.促销.或者游戏,你可以受益于使用原生JavaScript构建一个时钟,而不是拿到一个现成的 ...

随机推荐

  1. Centos 安装PHP-redis扩展

    从https://pecl.php.net/package/redis   里面找到自己安装的Redis对应版本的redis 1.获取已经安装的Redis版本扩展我这边安装的是4.0.1版本 wget ...

  2. 在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串)

    原文:在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  3. WPF打印控件内容

    当我们想打印控件内容时,如一个Grid中的内容,可以用WPF中PrintDialog类的PrintVisual()方法来实现 界面如下: XAML代码如下 <Grid> <Grid. ...

  4. robot framework 怎么验证搜索无记录,页面元素不存在

    假设你要验证搜索无记录,页面元素不存在,假设我搜索的文本为你好 页面展示为如下 搜索:你好 假设页面搜索有结果: 你好  class=vtext 你好1  class=vtext 你好2  class ...

  5. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  6. volatile和锁

    让编译器不要将变量缓存到寄存器,而是每次去访问主板上的内存 可见性 对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入 原子性 对任意单个volatile变量的 ...

  7. java线程分析方法

    1.查出占用资源大的线程的PID:xxxx ps -aux 2.安装java的sdk(含java虚拟机) jstack 试试是否安装成功 3.生成堆栈 jstack  -l  xxxx >> ...

  8. java 扫描微信公众号二维码,关注并登录逻辑

    场景:户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录. 逻辑: 系统生成带参数的临时二维码:参数 scene_str 自定义为唯一值(可以是uuid),临时二维码的生成方式参照官方接 ...

  9. L ==> E · L · K

    三剑客:Elastic Stack 在学习ELK前,先对 Lucene作基本了解. 今天才知道关系型数据库的索引是 B-Tree,罪过... 减少磁盘寻道次数 ---> 提高查询性能 Lucen ...

  10. 关于MySQL中的锁机制详解

    锁概述 MySQL的锁机制,就是数据库为了保证数据的一致性而设计的面对并发场景的一种规则. 最显著的特点是不同的存储引擎支持不同的锁机制,InnoDB支持行锁和表锁,MyISAM支持表锁. 表锁就是把 ...