在编写接口测试脚本时,要考虑一个问题:参数值从哪里获取

一种方式是可以通过数据库来获取,但是通过这次接口测试,我发现读取数据库有一个缺点:速度慢

可能和我的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接口的更多相关文章

  1. unittest-A接口的返回结果作为B接口的入参(设置全局变量)

    在A接口用例中设置全局变量: globals()["a"] = "用例A的返回结果" 在B接口用例中使用全局变量: b = globals()["a& ...

  2. Postman----登录接口返回的reponse中token值传递给其他接口的一个简单接口测试示例

    注: 在进行接口测试时,我们都需要使用登录,并且其他的接口都要在登录后进行,那么必不可少的会使用到将登录接口的reponse返回结果中的某些参数值需要进行返回,并传递给其他接口,这样才可以进行登录后的 ...

  3. python接口测试-项目实践(八) 完成的接口类和执行脚本

    脱敏后脚本 projectapi.py: 项目接口类 # -*- coding:utf-8 -*- """ xx项目接口类 2018-11 dinghanhua &quo ...

  4. python笔记39-unittest框架如何将上个接口的返回结果给下个接口适用(面试必问)

    前言 面试必问:如何将上个接口的返回结果,作为下个接口的请求入参?使用unittest框架写用例时,如何将用例a的结果,给用例b使用. unittest框架的每个用例都是独立的,测试数据共享的话,需设 ...

  5. python接口测试-项目实践(二)获取接口响应,取值(re、json)

    一 分别请求3个接口,获取响应. 第三方接口返回有两种:1 纯字符串  2 带bom头的json字串 import requests api1 = 'url1' response1 = request ...

  6. python接口测试中常见的两种接口依赖处理方式

    一.请求体的字段依赖 这种情况多数是在当前测试的接口,它的前置接口的请求体中的字段要拿来在当前的接口请求体中继续使用,比如修改用户信息的接口,该接口会使用到用户名的字段,该字段是由创建用户时的请求体中 ...

  7. Python接口测试实战1(上)- 接口测试理论

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  8. python接口测试:自动保存cookies

    接口测试中遇到上一个请求返回响应包含cookie(如下图登录请求的响应结果).需将cookies保存下来,后续请求自动带入,否则会提示未登录. python requests的cookie类型是< ...

  9. Python接口测试实战5(下) - RESTful、Web Service及Mock Server

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

随机推荐

  1. ELK日志分析系统(1)-基本环境搭建

    1. 概述 ELK = Elasticsearch + Logstash + Kibana Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开放REST和J ...

  2. Hibernate 框架 -HQL 语法

    HQL ( Hibernate Query Language ) 查询语言是面向对象的查询语言,也是在 Hibernate 中最常见的.其语法和 SQL 语法有一些相似,功能十分强大,几乎支持除特殊 ...

  3. 程序结构设计理论(Android)

    程序结构设计理论(Android) 作者:邓能财 2019年9月24日 个人简介 姓名:邓能财 年龄:26 毕业学校:东华理工大学 院系:理学院 专业:信息与计算科学 邮箱:2420987186@qq ...

  4. vue应用调试工具 vue-devtools安装

    方法一:chrome直接访问下面地址下载安装:(需要翻墙) https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejigli ...

  5. js-06-字符串

    一.查找字符串的字符串 a:indexOf:没有查询到返回值为-1: b:lastIndexoOf:查找到的为重复的最后一个: c:search 查找: var str="good good ...

  6. mongo [initandlisten] exception in initAndListen: 98 Unable to create/open lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating 2019-09-23T16:

    解决方法: 加权 sudo chmod -Rf 777 /data/db

  7. English: Class logogram

    IT # this is a IT type ISP ANOTHER # following is another logogram LCD PDA

  8. 发送RCS 消息摘录相关成功log

    //11-25 16:48:09.612102  2175  2726 I BugleDataModel: PendingMessagesProcessor: process from InsertN ...

  9. Spring整合JMS消息中间件

    1. 点对点模式 1.1消息生产者 (1)创建工程springjms_producer,在POM文件中引入SpringJms .activeMQ以及单元测试相关依赖 (2)在src/main/reso ...

  10. [Spring cloud 一步步实现广告系统] 12. 广告索引介绍

    索引设计介绍 在我们广告系统中,为了我们能更快的拿到我们想要的广告数据,我们需要对广告数据添加类似于数据库index一样的索引结构,分两大类:正向索引和倒排索引. 正向索引 通过唯一键/主键生成与对象 ...