python接口测试:如何将A接口的返回值传递给B接口
在编写接口测试脚本时,要考虑一个问题:参数值从哪里获取
一种方式是可以通过数据库来获取,但是通过这次接口测试,我发现读取数据库有一个缺点:速度慢
可能和我的sql写法有关,有些sql加的约束条件比较少,有时甚至全量查询,把所有结果遍历一遍,这样一轮下来直接就炸了,那速度比蜗牛还慢
这种方式给我的体验不太好,一方面本身连数据库这个操作我就不太愿意用,生怕对数据库造成什么伤害......
另一种方式就是写死参数,不过除非是一些固定的参数,比如按照某个类型查询,类型是固定的,那么可以事先定义一个列表或字典存放类型值,然后依次遍历即可;
否则一般不推荐写死参数,写死的话拓展性不强,换个测试环境,脚本可能就运行不起来了
还有就是通过接口获取想要的数据了,也就是一个接口能返回某些参数想要的值,那么就把这个接口的返回值传递给下个接口的参数
这样一来,参数值是动态生成的,即使切换环境,也可以在新环境获取参数值,然后再去发送请求
本质上接口间传递参数,其实就是处理上一个接口的返回数据,抽取出自己想要的某个字段或某一批字段
举个栗子:
有2个接口,A接口用于查询所有的标签数据,B接口需要传入一个标签,然后生成一条草稿数据,这样的话,可以在A接口查询出的所有标签中选择一个传给B
A接口的返回数据如下
seq表示标签编码,B接口本质上就是需要一条标签编码来生成数据
labelStatus表示标签状态,0表示启用,1表示未启用
{
'total': '',
'rows': [{
'seq': '151ceb6c0e624537a2b067d511c4c966',
'labelCode': '',
'labelName': '拼多多',
'labelStatus': 0,
'kseq': None,
'lseq': None
}, {
'seq': '1aa2ddfe896848cf893eebe6c37a79e6',
'labelCode': '',
'labelName': '京东',
'labelStatus': 0,
'kseq': None,
'lseq': None
}, {
'seq': '25879c28e8b54bf0b75168fc60c31a91',
'labelCode': '',
'labelName': '天猫',
'labelStatus': 0,
'kseq': None,
'lseq': None
}, {
'seq': '7715e67a153d484996a07af19ef33c09',
'labelCode': '',
'labelName': '苏宁',
'labelStatus': 0,
'kseq': None,
'lseq': None
}, {
'seq': '647733588fa34f60858e42ccd7357975',
'labelCode': '',
'labelName': '唯品会',
'labelStatus': 1,
'kseq': None,
'lseq': None
}]
}
先写一个方法,提取查询到的标签编码
def get_all_label(self):
"""获取菜单中所有标签数据"""
url = "http://127.0.0.1:8080/XXX"
payload = {
"page": "",
"rows": "",
"sort": "labelStatus",
"order": "asc"
} response = self.s.test_login().post(url, data=payload, headers=self.header, verify=False)
data = json.loads(response.content)
# print(data) try:
self.assertIn("rows", data)
self.assertIn("total", data) if data["rows"]:
labels = [] # 定义一个列表存查询到的所有标签数据
for t in data["rows"]:
"""以列表中嵌套字典的格式保存,易于调用""" if t["labelStatus"] == 0:
"""如果labelStatus为0则追加到列表中""" labels.append(
{"seq": t["seq"],
"labelCode": t["labelCode"],
"labelName": t["labelName"],
"labelStatus": t["labelStatus"]}
)
# print(labels)
return labels
else:
labels = None
return labels
except Exception as e:
print("请求url:", response.url)
print("传入参数:", payload)
raise e
B接口用于创建草稿数据,参数中用到A接口返回的标签编码seq
创建一个生成草稿数据的方法,在这个方法中,定义一个变量seq,用于接收标签编码
def add_draft(self, seq=None):
"""新增草稿"""
url = "http://127.0.0.1:8080/XXX"
payload = {
"title": "XX",
"applyType": 0,
"hotFlag": 1,
"content": "XX",
"replyContent": "XX",
"labelList[0].lseq": seq, # 接收传入的seq
"faqList[0].content": "XX",
"faqList[0].replyContent": "XX",
"fnType": 0
} response = self.s.test_login().post(url, data=payload, headers=self.header, verify=False)
data = response.json()
# print(data) try:
self.assertEqual(data["success"], "true")
self.assertEqual(data["successful"], True)return data except Exception as e:
print("请求url:", response.url)
print("传入参数:", payload)
raise e
最后利用上面2个方法编写一条用例
def test01(self):
try:
labels = self.get_all_label() # 调用查询标签方法,获取所有可用标签
# n = isinstance(labels, Iterable)
# print(n)
if labels:
label = random.choice(labels) # 从获取到的标签列表中随机取出一个
seq = label["seq"] # 从取出的一个标签中,获取其seq值
data = self.add_draft(seq) # 调用生成草稿数据方法,并将seq传入
print("使用的标签名:{},对应的标签seq:{},返回的草稿编码:{}".format(label["labelName"], label["seq"], data["data"])) elif labels is None:
print("标签菜单暂无可用数据,请先去添加标签") except Exception as e:
print("错误详情:", e)
raise e
在实际编写过程中,由于每个接口的实际情况不同,所以要做相应的处理,例如,
1. 在获取标签过程中,只有启用状态的标签才能使用,所以需要判断下标签的状态;
2. 需要考虑下假如标签菜单为空怎么办?这个时候获取标签的方法就拿不到数据,所以也要加个判断,没有标签数据时,这个方法要返回什么内容,以及后续接口做相应处理,避免当接收不到seq时报异常;
3. 另外就是有些接口在开发时定义的不是很规范,虽然返回的一大批数据,但是有些数据可能少个字段,例如上述获取标签接口的某些返回内容中缺少seq,那在提取每一组的seq时,就要判断seq这个字段是不是存在,存在则提取,不存在则略过。
其实这些问题也是在实际运行过程中发现的缺陷,很多异常情况没有考虑到,脚本不是写完就完了的,还要放到环境中运行,只有这样才会发现脚本不完善的地方。
这只是一个简单例子,实际情况可能更复杂一些,例如需要返回多个参数的情况或者把多个接口的返回值传递给一个接口等等;
不过道理都是一样的,要学会分析接口返回内容的结构,提取自己想要的值。更多细节以及技巧等待大家在实际使用过程中发现
完整demo:
login.py,使用cookie跳过验证码登录,可以参考:https://www.cnblogs.com/hanmk/p/9101275.html
# coding:utf-8 import requests
# from requests.cookies import RequestsCookieJar class Login: @staticmethod
def test_login():
s = requests.session() jar = requests.cookies.RequestsCookieJar() # 创建一个Cookie Jar对象
jar.set('XXX', 'xxx') # 向Cookie Jar对象中添加cookie值
jar.set('XXX', 'xxx')
jar.set('XXX', 'xxx')
s.cookies.update(jar) # 把cookies追加到Session中
return s
test.py
# coding:utf-8 import unittest
from hmk.login import Login
import warnings
import json
import random
from collections import Iterable class ModuleList(unittest.TestCase):
def setUp(self):
warnings.simplefilter("ignore", ResourceWarning)
self.s = Login()
self.url = 'http://127.0.0.1:8080/XXX'
self.header = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": "http://127.0.0.1:8080",
"Referer": "http://127.0.0.1:8080XXX",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36",
"X-Requested-With": "XMLHttpRequest"
} def get_all_label(self):
"""获取菜单中所有标签数据"""
url = "http://127.0.0.1:8080XXX"
payload = {
"page": "",
"rows": "",
"sort": "labelStatus",
"order": "asc"
} response = self.s.test_login().post(url, data=payload, headers=self.header, verify=False)
data = json.loads(response.content)
# print(data) try:
self.assertIn("rows", data)
self.assertIn("total", data) if data["rows"]:
labels = [] # 定义一个列表存查询到的所有标签数据
for t in data["rows"]:
"""以列表中嵌套字典的格式保存,易于调用""" if t["labelStatus"] == 0:
"""如果labelStatus为0则追加到列表中""" labels.append(
{"seq": t["seq"],
"labelCode": t["labelCode"],
"labelName": t["labelName"],
"labelStatus": t["labelStatus"]}
)
# print(labels)
return labels
else:
labels = None
return labels
except Exception as e:
print("请求url:", response.url)
print("传入参数:", payload)
raise e def add_draft(self, seq=None):
"""新增草稿"""
url = "http://127.0.0.1:8080/XXX"
payload = {
"title": "XXX",
"applyType": 0,
"hotFlag": 1,
"content": "XXX",
"replyContent": "XXX",
"labelList[0].lseq": seq, # 接收传入的seq
"faqList[0].content": "XXX",
"faqList[0].replyContent": "XXX",
"fnType": 0
} response = self.s.test_login().post(url, data=payload, headers=self.header, verify=False)
data = response.json()
# print(data) try:
self.assertEqual(data["success"], "true")
self.assertEqual(data["successful"], True)return data except Exception as e:
print("请求url:", response.url)
print("传入参数:", payload)
raise e def test01(self):
try:
labels = self.get_all_label() # 调用查询标签方法,获取所有可用标签
# n = isinstance(labels, Iterable)
# print(n)
if labels:
label = random.choice(labels) # 从获取到的标签列表中随机取出一个
seq = label["seq"] # 从取出的一个标签中,获取其seq值
data = self.add_draft(seq) # 调用生成草稿数据方法,并将seq传入
print("使用的标签名:{},对应的标签seq:{},返回的草稿编码:{}".format(label["labelName"], label["seq"], data["data"])) elif labels is None:
print("标签菜单暂无可用数据,请先去添加标签") except Exception as e:
print("错误详情:", e)
raise e if __name__ == '__main__':
# unittest.main()
suite = unittest.TestSuite()
suite.addTest(ModuleList('test01'))
runner = unittest.TextTestRunner()
runner.run(suite)
喜欢点个赞吧,也可以关注我的公众号喲,更多精彩等你发现~~
python接口测试:如何将A接口的返回值传递给B接口的更多相关文章
- unittest-A接口的返回结果作为B接口的入参(设置全局变量)
在A接口用例中设置全局变量: globals()["a"] = "用例A的返回结果" 在B接口用例中使用全局变量: b = globals()["a& ...
- Postman----登录接口返回的reponse中token值传递给其他接口的一个简单接口测试示例
注: 在进行接口测试时,我们都需要使用登录,并且其他的接口都要在登录后进行,那么必不可少的会使用到将登录接口的reponse返回结果中的某些参数值需要进行返回,并传递给其他接口,这样才可以进行登录后的 ...
- python接口测试-项目实践(八) 完成的接口类和执行脚本
脱敏后脚本 projectapi.py: 项目接口类 # -*- coding:utf-8 -*- """ xx项目接口类 2018-11 dinghanhua &quo ...
- python笔记39-unittest框架如何将上个接口的返回结果给下个接口适用(面试必问)
前言 面试必问:如何将上个接口的返回结果,作为下个接口的请求入参?使用unittest框架写用例时,如何将用例a的结果,给用例b使用. unittest框架的每个用例都是独立的,测试数据共享的话,需设 ...
- python接口测试-项目实践(二)获取接口响应,取值(re、json)
一 分别请求3个接口,获取响应. 第三方接口返回有两种:1 纯字符串 2 带bom头的json字串 import requests api1 = 'url1' response1 = request ...
- python接口测试中常见的两种接口依赖处理方式
一.请求体的字段依赖 这种情况多数是在当前测试的接口,它的前置接口的请求体中的字段要拿来在当前的接口请求体中继续使用,比如修改用户信息的接口,该接口会使用到用户名的字段,该字段是由创建用户时的请求体中 ...
- Python接口测试实战1(上)- 接口测试理论
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- python接口测试:自动保存cookies
接口测试中遇到上一个请求返回响应包含cookie(如下图登录请求的响应结果).需将cookies保存下来,后续请求自动带入,否则会提示未登录. python requests的cookie类型是< ...
- Python接口测试实战5(下) - RESTful、Web Service及Mock Server
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
随机推荐
- Git实战指南----跟着haibiscuit学Git(第十一篇)
笔名: haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...
- JavaScript 日期格式
有四种 JavaScript 日期输入格式: 类型 实例 ISO 日期 "2018-02-19" (国际标准) 短日期 "02/19/2018" 或者 &quo ...
- FlowPortal 6.00c 使用xFormDesigner复制粘贴中文总是乱码
环境: Windows Server 2016中文版 FlowPortal 6.00C 问题: 使用xFormDesigner 在源码选项卡复制粘贴中文总是乱码. 解决办法: 控制面板---区域--- ...
- 第03讲 fragment
Fragment 官网文档:https://developer.android.google.cn/guide/components/fragments 什么是Fragment 在手机上,Activi ...
- 【Java基础】Annotation 的本质和自定义实现
Java 中注解的实现原理 一.引言 在 Java5 之前,利用 xml 进行配置是各大框架的常规操作,这种方式可以实现松耦合并完成框架中几乎所有需要的配置,但随着项目的扩展,xml 文件本身的内容将 ...
- katalon Studio之WebUi自动化测试视频教程持续更新
通知...通知...通知... 为了更好的把katalon Studio自动化测试工具推广给大家,最近在B站中开通了视频专栏,地址如下: https://www.bilibili.com/video/ ...
- LVS的工作模式介绍和NAT模式&DR模式实验步骤
一:LVS介绍 二.LVS的NAT和DR模式的实验及配置步骤 一.LVS的简单介绍 linux virtual server 简单来讲lvs是一段内核代码 类似于netfilter本身是一框架但不提供 ...
- Linux系统学习 十三、VSFTP服务—相关文件
常见的FTP服务器程序 IIS.Serv-U (windwards中) wu-ftpd(淘汰了).Proftpd (Linux中) vsftpd(Very Secure ...
- ansible执行带有环境变量的脚本不生效
1背景 jenkins发布时,使用ansible执行远程主机上的启动tomcat脚本发现不生效,启动tomcat的脚本中有环境变量. ansible主机为:172.16.35.8 tomcat服务器为 ...
- 多次调用settimeout 如何使用单例模式
<script> function aaa() { window.counter = window.counter||1; console.log(window.counter); win ...