httprunner如何提取数据串联上下游接口
httprunner进行接口测试时,从上一个接口提取参数传递给下游接口,如何获取数据里最后一个值?
突然被学员问道一个httprunner的问题,惭愧的是大猫之前没有是通过httprunner,又不好意思说不会,只能硬着头皮去看源码了。

问题其实很简单,怎么处理我不管,反正你得给答案。看一眼同学反馈的截图,确实不难,问题很简单。请求某一个接口,接口返回的content里包含多个字段,需要获取到最后一个字典里的数据。是不是觉得很简单?

对于这么具体的问题,大猫当然是第一反应去百度啦!当然,如果能简单百度到答案,学员也不会来问我,因此,结果可想而知,百度没有标准答案!

不过百度一点用处也没有么,也不尽然,至少对于一只从来没有使用过httprunner的大猫来说,知道从响应提取数据使用extract关键字。
既然百度没有标准答案,我们就代码里找,大猫最不怕的就是看代码,大江大浪都走过来了,还能这几千行代码里翻船?
看代码先要去github把代码拉取到本地(这里就不写怎么做了),用pycharm打开,然后使用pycharm的“find in path...”进行全局查找,像这样:


我们点击去看下代码的实现细节,没准可以发现蛛丝马迹。
if not extractors:
return {}
logger.log_debug("start to extract from response object.")
extracted_variables_mapping = OrderedDict()
extract_binds_order_dict = utils.ensure_mapping_format(extractors)
for key, field in extract_binds_order_dict.items():
extracted_variables_mapping[key] = self.extract_field(field)
return extracted_variables_mapping
代码实现相当简洁,实例化一个OrderedDict用于存储提取后的数据,采用extract_field函数来执行具体的提取数据操作。我们接着看extract_field函数。
text_extractor_regexp_compile = re.compile(r".*\(.*\).*")
if text_extractor_regexp_compile.match(field):
value = self._extract_field_with_regex(field)
else:
value = self._extract_field_with_delimiter(field)
extract_field的核心逻辑也非常简洁,采用re.compile判断表达式是否为正则,是的话执行正则表达式提取_extract_field_with_regex,如果不是正则采用分隔符提取方式,_extract_field_with_delimiter,我们需要的是分隔符方式提取,因此看_extract_field_with_delimiter函数的实现。
_extract_field_with_delimiter函数实现略微复杂,函数里对查询字符串进行了分级处理,content.person.name.first_name被分成top_query:content和sub_query:[person, name, first_name]。
同时不同的top_query有不同的处理方法,例如top_query若是status_code,encoding,ok,reason,url等则不能有sub_query,否则会抛出异常(这里和响应对象结构有关系);
if top_query in ["status_code", "encoding", "ok", "reason", "url"]:
if sub_query:
# status_code.XX
err_msg = u"Failed to extract: {}\n".format(field)
logger.log_error(err_msg)
raise exceptions.ParamsError(err_msg)
return getattr(self, top_query)
对于top_query是cookies和headers的处理,若存在sub_query则以sub_query为key进行取值,否则返回cookie或header整体。
elif top_query == "cookies":
cookies = self.cookies
if not sub_query:
# extract cookies
return cookies
try:
return cookies[sub_query]
except KeyError:
err_msg = u"Failed to extract cookie! => {}\n".format(field)
err_msg += u"response cookies: {}\n".format(cookies)
logger.log_error(err_msg)
raise exceptions.ExtractFailure(err_msg)
如果top_query是content,text或json则使用query_json函数进一步处理。当然,处理前进行了一次判断,sub_query是字典、列表还是数字。
elif top_query in ["content", "text", "json"]:
try:
body = self.json
except exceptions.JSONDecodeError:
body = self.text
if not sub_query:
# extract response body
return body
if isinstance(body, (dict, list)):
# content = {"xxx": 123}, content.xxx
return utils.query_json(body, sub_query)
elif sub_query.isdigit():
# content = "abcdefg", content.3 => d
return utils.query_json(body, sub_query)
else:
# content = "<html>abcdefg</html>", content.xxx
err_msg = u"Failed to extract attribute from response body! => {}\n".format(field)
err_msg += u"response body: {}\n".format(body)
logger.log_error(err_msg)
raise exceptions.ExtractFailure(err_msg)
query_json函数是实现取值的关键,函数使用分隔符讲sub_query切分成字符串数据,采用循环遍历数据。
for key in query.split(delimiter):
if isinstance(json_content, (list, basestring)):
json_content = json_content[int(key)] <- 这里是关键
elif isinstance(json_content, dict):
json_content = json_content[key]
else:
logger.log_error(
"invalid type value: {}({})".format(json_content, type(json_content)))
raise_flag = True
这里如果数据是列表则将key转化为数字取值,否则认为是字典直接用key取值。既然代码是转化成整形,整数有正整数,负整数和零,理论上提取数据的字符串可以有content.person.-1.name.first_name
这样的存在。这里可以理解为从content里取最后一个person的name的first_name。

另外,这里多说一句,可以看见httprunner的代码并不难,python测开的学员应该都能看到懂,希望大家多看看开源框架的代码,提升自己的代码能力,也希望大家报名我的课程。
作 者:Testfan 大猫
出 处:微信公众号:自动化软件测试平台
版权说明:欢迎转载,但必须注明出处,并在文章页面明显位置给出文章链接
httprunner如何提取数据串联上下游接口的更多相关文章
- HttpRunner学习3--extract提取数据和引用
前言 在HttpRunner中,我们要想从当前 HTTP 请求的响应结果中提取参数,可以通过 extract 关键字来实现. 本人环境:HttpRunner V1.5.8 测试场景 在这里,我将以一个 ...
- HttpRunner学习4--使用正则表达式提取数据
前言 在HttpRunner中,我们可通过extract提取数据,当响应结果为 JSON 结构,可使用 content 结合 . 运算符的方式,如 content.code,用起来十分方便,但如果响应 ...
- scrapy框架Selector提取数据
从页面中提取数据的核心技术是HTTP文本解析,在python中常用的模块处理: BeautifulSoup 非常流行的解析库,API简单,但解析的速度慢. lxml 是一套使用c语言编写的xml解析 ...
- JMETER从JSON响应中提取数据
如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...
- 如何使用JMETER从JSON响应中提取数据
如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...
- 返回数据中提取数据的方法(JSON数据取其中某一个值的方法)
返回数据中提取数据的方法 比如下面的案例是,取店铺名称 接口返回数据如下: {"Code":0,"Msg":"ok","Data& ...
- [数据科学] 从csv, xls文件中提取数据
在python语言中,用丰富的函数库来从文件中提取数据,这篇博客讲解怎么从csv, xls文件中得到想要的数据. 点击下载数据文件http://seanlahman.com/files/databas ...
- 曲线提取数据Engauge Digitizer
可导出CSV格式数据 其它参考: http://blog.sina.com.cn/s/blog_4ae65b4d0100z8cg.html 其它曲线提取数据的软件还有: GetData.Windig ...
- 提取数据用strpos函数比较,预期和实际不符问题解决
在我提取数据时,数据是一串字符串,第一个数据和要比较的字符是相等的可是却是相反的结果 . 测试if(0==false)结果如图 执行结果 说明0和false相等.我的程序开始是这样的 第一个数据是正确 ...
随机推荐
- C# NAudio 录制声音和显示波形图
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- [VBA]去重汇总
问题描述:汇总多个工作表的指定字段到sheet1里面,并去除重复的字段内容. Sub 去重汇总() Dim sht As Worksheet, j As Integer, x As Integer S ...
- 第五章 SpringCloud之Eureka-Client使用RestTemplate实现服务之间的调用
注意:这个章节,请结合前几章节一起使用,因为其要调用上一章节的服务 1.pom.xml <?xml version="1.0" encoding="UTF-8&qu ...
- Python学习之==>字符串格式化
1.第一种方式 import datetime today = datetime.date.today() username = input('请输入用户名:') welcome = '欢迎光临:' ...
- [转] javascript 正则表达式提取数字使用
简述: 测试了一下js的正则表达式函数match 用来从一个字符串里挑出非0开头的数字, 放入一个array里, 之后join(',')之后输出 知识点: 1. 用match函数, 提取一个字符串当中 ...
- Redis 入门 3.2.4 命令拾遗
Redis 入门 3.2 字符串类型 3.2.4 命令拾遗 1. 增加指定的整数 INCRBY key increment INCRBY命令与INCR命令基本一样,只不过前者可以通过increme ...
- Cocos2d-X多线程(4) 在子线程中进行网络请求
新版本的android系统已经不允许在UI线程中进行网络请求了,必须新建一个线程. 代码实操: 头文件: #ifndef __TestThreadHttp_SCENE_H__ #define __Te ...
- 磊哥的密码箱icpc11526
问题 D: 磊哥的密码箱 时间限制: 1 Sec 内存限制: 128 MB提交: 238 解决: 61[提交] [状态] [命题人:admin] 题目描述 磊哥有个密码箱,里面装的都是令磊哥羞羞的 ...
- redis缓存与数据一致性
目录 缓存 缓存穿透 缓存雪崩(缓存失效) 缓存击穿(热点key) 缓存并发竞争(并发set) 数据一致性 缓存(双写)一致性 Redis集群(Redis-cluster)一致性原理 哨兵(Senti ...
- Hibernate——简单的增、删、改、查操作
思路: 1.导入hibernate jar包 2.导入mysql jar包 3.创建数据库 4.创建java实体类 5.编写hibernate.cfg.xml配置文件 6.编写dao类 目录: 数据表 ...