Python接口自动化之接口依赖
作者:软件测试自动化测试 发布时间:2021-09-03 15:53:09
一、场景说明
在面试接口自动化时,经常会问,其他接口调用的前提条件是当前用户必须是登录状态,如何处理接口依赖?
在此之前我们介绍过session管理器保存会话状态。如果接口请求需要携带token,那么又如果处理呢?以下详细介绍。
未登录状态下,直接请求充值接口的异常场景:
import unittest
import requests
class TestRecharge(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_recharge(self):
url = 'http://127.0.0.1:8888/recharge'
payload = {
"member_id": 100004312,
"amount": 80
}
res = requests.post(url,json=payload)
print(res.json())
if __name__ == '__main__':
unittest.main()
运行结果如下:
{'code': 1003, 'msg': '未授权或token已过期'}
二、token处理思路
在处理之前,token灵魂三连问:
如何获取token?
获取的token如何管理?
其他接口如何携带token?
思路如下:
1.抽取登录接口返回值中的token;
2.使用全局变量存储token。token可以存到yaml或者json或者ini的配置文件里,以下介绍将token作为类属性;
3.其他接口将token值放入请求头,发送请求;
三、JsonPath基本用法
我们需要从登录接口中提取出token,这里介绍JsonPath基本用法。
1、JsonPath介绍
JsonPath为Json文档提供了解析能力,通过使用JsonPath,你可以方便的查找节点、获取想要的数据,JsonPath是Json版的XPath。
2、JsonPath语法
JsonPath | 说明 |
---|---|
$ | 文档根元素 |
@ | 当前元素 |
. 或[] | 匹配下级元素 |
.. | 递归匹配所有子元素 |
* | 通配符,匹配下级元素 |
[] | 下标运算符,根据索引获取元素,JsonPath索引从0开始 |
[,] | 连接操作符,将多个结果拼接成数组返回,可以使用索引或别名 |
[start:end:step] | 数据切片操作 |
?() | 过滤表达式 |
这么多语法规范,大家会觉得一脸懵逼吧,细心的小伙伴会发现语法中 .. 表示递归匹配所有子元素,简单粗暴,用..获取所有匹配的子元素,通过索引拿到想要的值,以下以实战进行演练。
3、JsonPath源码
def jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True):
"""traverse JSON object using jsonpath expr, returning values or paths"""
obj: 需要解析的对象,比如接口的返回值。
expr: 匹配的表达式。
4、JsonPath实战
以下编写代码进行演示。
from jsonpath import jsonpath
# json格式结果
res = {
"code": 0,
"msg": "OK",
"data": {
"token_info": {
"token_type": "Bearer",
"expires_in": "2020-05-28 13:07:29",
"token": "eyJhbGciOiJIUzUxAiJ9.eyJtZW1iZZJfaWQiOjEwMDA1MTMxNSwiZXhwIjoxNTkwNjQyNDQ5fQ.s6A7pzLILf9tqpEDAU9wIPGGLGkgKEQ6EBHq26l-eUM5seCb48DWalkE7u16iRZv3uzD5hIDFbw41Jmi9V0T_Q"
}
}
}
# 获取res中的token
token = jsonpath(res,'$..token')[0]
print(token)
响应结果为:
eyJhbGciOiJIUzUxBiJ9.eyJtZW1iZZJfaWQiOpEwMDA1MTMxNSwiZXhwIjoxNTkwNjQyNDQ5fQ.s6A7pzLILf9tqpEDAU9wIPGGLGkgKEQ6EBHq26l-eUM5seCb48SWalkE8u16iRZv3uzD5hIDFbw41Jmi9V0T_Q
四、token依赖实例
①在config/setting.py配置文件中,配置全局的域名或IP。
class DevConfig():
# 项目的域名或IP
host='http://127.0.0.1:8888'
config = DevConfig()
②在config/config.yaml文件中,存入登录账号。
config.yaml
user:
mobile_phone: '155********'
pwd: '12345678'
③在项目根目录下,新建文件夹middleware,文件夹下新建文件helper.py,用于处理token。
④首先编写登录接口,返回接口数据。
helper.py
from common.requests_handler import RequestsHandler
from config.setting import config
from common.yaml_handler import yaml_data
def login():
"""登录,接口返回token"""
req = RequestsHandler()
res = req.visit('post', config.host+'/login', json=yaml_data['user'])
return res
print(login())
运行结果如下:
{
'code': 0,
'msg': 'OK',
'data': {
'token_info': {
'token_type': 'Bearer',
'expires_in': '2020-05-26 13:31:41',
'token': 'eyJhbGciOiJIUpUxMiJ9.eyJtZW1iZXJfaWQiOjEwMDA1MTMxNSwiZXhwIjoxNTkwNDcxMTAxfQ.4QDNdQ-Wyecvpv7yRnMlCx1ZXpAlb8vpohxHht5OfNcjGn_yTaISyhmn7OMzjMGlz68sJ_uFbCh2NhIaO2p_Lg'
}
}
}
⑤接下来编写函数,获取登录接口返回值并提取token和token_type进行拼接 。这里要使用jsonpath模块提取返回的token和token_type。
helper.py
def save_token():
"""保存token信息"""
res = login()
token = jsonpath(res,'$..token')[0]
token_type = jsonpath(res,'$..token_type')[0]
token = " ".join([token_type, token])
return token
print(save_token())
运行结果如下:
Bearer eyJhbGciOJIPzUxMiJ9.eyJtZW1iZXJfaWQiOjEwMDA1MTMxNSwiZXhwIjoxNTkwN
⑥最后定义类,将token作为类属性,整体代码如下:
helper.py
from common.requests_handler import RequestsHandler
from config.setting import config
from common.yaml_handler import yaml_data
from jsonpath import jsonpath
def login():
"""登录,返回token信息"""
req = RequestsHandler()
res = req.visit('post', config.host+'/login', json=yaml_data['user'])
return res
def save_token():
"""保存token信息"""
res = login()
token = jsonpath(res,'$..token')[0]
token_type = jsonpath(res,'$..token_type')[0]
token = " ".join([token_type, token])
Context.token = token
return token
class Context:
"""将token作为类属性"""
token = ''
if __name__ == '__main__':
print(save_token())
运行结果如下:
Bearer eyJhbGciOiJIUzUxMiJ9.eyJtZW1iZXJfaWQiOjEwMDA1MTMxNSwiZXhwIjoxNTkwNDcz
⑦充值接口携带token请求。
import unittest
import requests
from middleware.helper import Context, save_token
class TestRecharge(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_recharge(self):
save_token()
token = Context.token
url = 'http://127.0.0.1:88888/recharge'
payload = {
"member_id": 100051315,
"amount": 80
}
res = requests.post(url,json=payload)
print(res.json())
if __name__ == '__main__':
unittest.main()
运行结果为:
{
'code': 0,
'msg': 'OK',
'data': {
'leave_amount': 240.0,
'mobile_phone': '155********',
}
}
总结:
本文主要介绍如何提取token、将token作为类属性全局调用及充值接口如何携带token进行请求。
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
来源:https://blog.csdn.net/ZangKang1/article/details/119838519


猜你喜欢
- 网上关于SQL优化的教程很多,但是比较杂乱。近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充。(1) 选择
- 本文实例讲述了PHP基于phpqrcode类生成二维码的方法。分享给大家供大家参考,具体如下:使用PHP语言生成二维码,还是挺有难度的,当然
- 字段是Python是字典中唯一的键-值类型,是Python中非常重要的数据结构,因其用哈希的方式存储数据,其复杂度为O(1),速度非常快。下
- 一. vue-amap,一个基于 Vue 2.x 和高德地图的地图组件 https://elemefe.github.io/vue-amap
- 本文实例讲述了python实现获取单向链表倒数第k个结点的值。分享给大家供大家参考,具体如下:#初始化链表的结点class Node():
- 注:本文所说的视觉设计师专指网页视觉设计师。网页设计师与平面设计师都归类为设计师,其实这两个职业是跨行业的,虽然有很多设计师一直在跨行业工作
- 前言python中有两种循环,while和for,两种循环的区别是,while循环之前,先判断一次,如果满足条件的话,再循环,for循环的时
- 一、测试常用规则一个测试单元必须关注一个很小的功能函数,证明它是正确的;每个测试单元必须是完全独立的,必须能单独运行。这样意味着每一个测试方
- 用MYSQL 5.7.9 作为ZABBIX 2.4.7 的监控数据库. 前段时间开启了慢查询日志, 后来发现慢查询日志膨胀到了700M查看最
- 这几天正在追剧,原名《大秦帝国之天下》的《大秦赋》,看着看着又想把前几部刷一遍了,但第一部《裂变》自己没有高清资源,搜了一波发现yout
- 本文实例讲述了Python反射的用法。分享给大家供大家参考,具体如下:在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或
- anaconda指的是一个开源的Python
- 复制表结构及其数据下面这个语句会拷贝数据到新表中。注意:这个语句其实只是把select语句的结果建一个表,所以新表不会有主键,索引。crea
- 第一步,建立一个CPP的DLL工程,然后写如下代码,生成DLL#include <stdio.h> &nb
- 前两天看见有人问静态网页加密问题,就写了这个代码稍微有些长,解释一下思路:加密时:先把用户的密钥A用md5加密为B,然后用B异或源文件S0得
- 依托于互联网的发达,我们可以随时随地利用一些等车或坐地铁的碎片时间学习以及了解资讯。同时发达的互联网也方便人们能够快速分享自己的知识,与相同
- 本文实例讲述了Python实现阿拉伯数字和罗马数字的互相转换功能。分享给大家供大家参考,具体如下:前面一篇介绍了《Java实现的求解经典罗马
- 前言最近几天,研究了一下一直很好奇的爬虫算法。这里写一下最近几天的点点心得。下面进入正文:你可能需要的工作环境:Python 3.6官网下载
- 这篇文章主要介绍了简单了解Django ORM常用字段类型及参数配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- 使用if…elif…elif…else 实现switch/case可以使用if…elif…elif..else序列来代替switch/cas