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接口测试实战 ...
随机推荐
- ASP.NET MVC中使用MvcPager异步分页+在分页中复选框下一页上一页也保持选中
ASP.NET MVC 分页使用的是作者杨涛的MvcPager分页控件 地址:http://www.webdiyer.com/mvcpager/demos/ajaxpaging/ 这个分页控件在里面 ...
- C lang:character input and output (I/O)
Xx_Introduction Character input and output is by more line character conpose of the text flow Defin ...
- iOS正则表达式解决实际问题
问题:上海市徐汇区桂林路158号1202室 字符串长度不固定,数字长度也不固定.截取第二组数字. 方法一:[正则表达式] NSString * str = @"上海市徐汇区桂林路158号12 ...
- mysql创建用户后无法进入
说明 在mysql中添加用户: #mysql -u root -p >use mysql: >update user set password="" where use ...
- 【好书推荐】《剑指Offer》之硬技能(编程题7~11)
本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword <[好书推荐]& ...
- 基于Python的SQL Server数据库对象同步轻量级实现
缘由 日常工作中经常遇到类似的问题:把某个服务器上的某些指定的表同步到另外一台服务器.类似需求用SSIS或者其他ETL工作很容易实现,比如用SSIS的话就可以,但会存在相当一部分反复的手工操作.建源的 ...
- sql语句中给列参数取别名及相关注意事项
1.使用双引号 select count(*) "总数" from table: 2.使用单引号 select count(*) '总数' from table: 3.直接加别名, ...
- How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 394798.1)
How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 39479 ...
- 进制转换器V1.0_Beta
一.截图部分 二.代码部分: char2num() 作用:将字符转化成对应的数字 e.g. '9'->9 'A'->10 int char2num(char ch) ...
- Springboot整合Mybatis实现级联一对多CRUD操作
在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...