python代码学习——接口自动化一(接口基础与requests)

接口基础知识

  • 接口在广义上可以分为内部接口和外部接口,内部接口指的是公司内部的接口,例如登录;外部接口指的是调用第三方的接口,例如获取验证码、支付等等
  • 按照分类,可以分为硬件接口和软件接口,软件接口又分为程序内部接口和外部接口
    • 硬件接口:指的是两个硬件设备之间的连接方式
    • 软件接口:简单的来说,就是软件程序之间的数据交互通道
    • 程序内部接口:同一个系统中模块和模块之间的接口
    • 外部接口:是跨系统平台与平台之间的对接,例如微信、支付宝的支付接口等
  • 按照不同的请求协议,分为http、webservice、dubbo、socket,如何得知公司产品的协议?答案:问开发
    • 进行接口测试的工具:postman,jmeter(http)、soapui(webservice)
  • 接口的本质:调用类里面的方法
  • http协议请求分为get、post、delete、head、optioon
  • webservice:经过封装的post请求
  • 什么是接口功能测试?——本质上是基于某种协议,模拟客户端发送请求给服务器,服务器返回响应数据,然后对响应数据进行分析,判断和我们的预期是否一致,从而验证功能是否正确

为什么要做接口测试

在这里插入图片描述

  • 进行接口测试的优点:
    • 接口测试更早介入,降低研发的成本
    • 更加容易实现自动化,因为其比UI稳定
    • 更加接近于底层,发现buug影响范围更广

如果要进行接口测试,没有接口文档的话要怎么做

  • 首先,可以考虑推送开发去完善接口文档
  • 或者:自力更生,抓包,F12查看,咨询开发

协议和HTTP请求

  • 不论是哪一种接口,本质上都是通过某一种传输协议(例如http、https、webservice),在客户端和服务器之间传输数据
  • http协议是目前最为广泛的协议,https是在http的基础上做了一层加密,会更加安全
  • webservice协议的接口,一般是使用soap协议通过http进行传输,请求的报文和相应的报文一般是xml格式

Http协议的细则

  • 一个http请求包括:head(请求头)信息、响应信息、cookies、html、缓存
  • 请求头:保存请求的一些配置信息,例如请求的长度,content_type,cookies等
  • 请求头信息并不是每一次请求都要,但是如果请求中必须要请求头(headers),那么必须要加
  • 请求头跟随requesr中的hearers参数,以字典/json的形式发送
  • url:请求地址
  • get/post: 请求方法
  • 响应头:服务器返回回来的数据,一般是json
  • Request Payload:请求数据,一般传递的数据是json

http常见的状态码

  • 200 :正常,一切正常,服务器接收请求也作出了正确的处理
  • 4XX:客户端错误:
    • 404:找不到,服务器不存在客户机所请求的资源
    • 403:禁止 服务器理解客户请求,但是拒绝处理,通常由服务器上的文件或目录的权限导致
  • 3XX:表示重定向相关
    • 302:临时重定向:请求地址的文档被移动或者删除,文档新的url在location响应头中给出
    • 301:永久重定向
    • 304:未修改:表示客户机器缓存的版本是最新的,应该继续使用他(具体说直接取缓存的数据),比如说前端js,主要指的是静态资源
  • 5XX:表示服务器的错误
    • 500:服务器内部程序出现错误
    • 502:网官错误,一般由服务器重启导致
    • 504:超时

get请求和post请求的区别

  • 传参位置不同:
    • get请求的参数拼接在接口地址后面,通过?进行拼接,多个参数之间会使用&连接,其是查询参数
    • post请求会将参数存放在请求体中
  • 传递参数的长度有限制
    • get请求传惨会有长度限制
    • post请求理论上没有长度限制,如果要传递大量数据的话,一般会使用post的方式
  • 安全性也有区别
    • get请求因为参数直接写在地址后面,所以相对而言报参数容易暴漏
    • post请求,相比get请求而言,更加安全

cookies与session

  • cookies:在客户端村存储用户的一些数据,例如用户名或浏览器记录
  • seeeion:在服务器及用户的请求状态,一般默认时间是30min,超时重新登录,有session决定。一般以session_id的形式呈现出来
  • 机制:session_id会记录在cookies中,每次请求,cookies的所有信息都会传给服务器,服务器通过session_id来识别是否是同一个用户的请求,不是一个用户的话,会要求用户重新登录
  • 这种机制的原因:http请求是无状态的、无标记的
  • session存在过期,cookies没有过期

访问授权与鉴权

  • 鉴权:访问的接口是否正常,是否非法访问,越过前端访问,token
  • 授权:是否只有访问接口的权限 ,常出现在加密的或者收费的第三方接口,并不是任何人都可以访问的,如果要正常访问,必须要传key,一般来说是唯一的、全局的、动态的,具有一定的特征
  • 验签,常出现在app或SDK的应用中,参靠以下网址:https://blog.csdn.net/sjy8207380/article/details/79232644
  • jemeter和soapUI的使用方法:

如何用python做接口测试

  • 利用python去发起http请求
  • 可利用urlib、urlib2、requests模块都可实现利用python发起http请求
  • 在此只讲解requests模块
  • 首先安装requests第三方库
  • 导入requests模块
  • 如果遇到接口不会处理怎么办?http://docs.python-requests.org/zh_CN/latest/

Requests模块

  • 通过代码发起的请求与通过网站/app/接口测试工具发起的请求是一样的,都是从客户端发起
  • requests 的简单使用样例
import requests

url = 'https://xgsj.istarshine.com/login'
data = requests.get(url)
print(data)

Get请求

  • requests中的get模块,就是一个函数
  • 存在return的返回值,返回的是一个对象,可用变量来接受存储这个值,打印结果如下:
    在这里插入图片描述
  • get中存在三个参数,url、param和**kwargs;其中param存在默认参数None
  • url指的是数据地址,param指的是数据发送的格式,**kwargs指的是请求的时候带的参数
  • get返回的是一个request请求函数
  • 以下是get函数的的代码详情
    在这里插入图片描述

request 请求函数

  • request 中存在method、url和 **kwargs(关键字参数,不传入也可以)三个参数
  • 其中method指的是请求方式,url指的是请求地址,**kwargs是关键字参数默契意味着参数会以键值对的形式传入
  • 其中的关键字参数必须传requeat指定的那些参数,例如:method、url、data、json、params、headers、cookies、files、proxies(代理)、auth、time-out、verify、class、request等等
  • requeats支持的请求方式有许多种,`GET, OPTIONS, HEAD, POST, PUT, PATCH, 和 DELETE.都是http请求的method,但是常用的是get和post请求
    在这里插入图片描述

post请求

  • 如果一个url,使用get请求返回200,使用post请求返回404,说明url不支持post请求
  • post请求中,根据headers中的content-type不同,可以将其传参形式分为三种,data,json和file
  • post请求中存在url、data、json和关键字参数
  • url指的是请求地址;data和json是默认参数,含带默认值None;
  • post请求中,根据headers中的content-type不同,可以将其传参形式分为三种,data,json和file
  • headers可以不传,默认为None
  • 存在return返回值,返回值是兑现对象在这里插入图片描述

json形式传参

  • 如果content-type的传参为【application/json】,那么就需要传递json参数,requests中也需要用json接收
import requests
json= {"key1":"value1","key2":"value2"}
res = requests.post('http://www.httpbin.org/post',json=json)

文件形式传参

  • 当我们需要传输大容量的数据到服务端时(比如上传文件),我们通常使用content-type=【multipart/form-data】传参类型
  • 在requests中通过指定files参数
url = 'http://httpbin.org/post'
# files为字典类型数据,上传的文件为键值对的形式,参数名作为键,
# 参数值是一个元组,内容为以下格式(文件名,打开的文件流,文件类型)
files = {
"file": ("test.png", open("test.png", "rb"), "images/png")
}
r = requests.post(url, files=files) #通过files参数来传递file数据
  • 代码示例如下:
import pathlib

import requests

headers = {"Authorization":"bearere461bdb3-986f-42f8-8100-9545bf9d6c93"}
path_png = pathlib.Path(__file__).absolute().parent /"ApiAndExc"/"data"/"panda.png"
file_data = {"file":("panda.png",open(f"{path_png}","rb"),"images/png")}
res = requests.post("http://shop.lemonban.com:8107/p/file/upload",files=file_data,headers=headers)
print(res.text)
===========================run_result============================
{"resourcesUrl":"http://shop.lemonban.com:8108/","filePath":"2023/11/d4d065a9450e4e4d829e447131f4e4a2.png"}

data传参

  • 非json和文件类型的传参方式,基本都是data接收,例如常见的表单传参:content-type= 【application/x-www-form-urlencoded】
import requests
data = {"key1":"value1","key2":"value2"}
res = requests.post('http://www.httpbin.org/post',data=data)

requests模块的return返回

  • 不论是get还是post,其请求的结果return返回的都是对象,是个响应实体
  • 一个repose包含了响应头、响应正文和状态码和相应时间

查看模块返回信息

  • 使用headers来查看响应
  • 使用text来查看正文
  • 使用status_code来查看code码
  • 使用elapsed.total_seconds()来查看接口的响应时间
import requests

url = 'http://shop.lemonban.com:8107/login'
login_param = {"principal":"lemon_auto","credentials":"lemon123456","appType":3,"loginType":0}
headers = {"Content-Type":"application/json"}
data_1 = requests.post(url,json=login_param,headers=headers)
print(data_1)
data_headers = data_1.headers#查看响应头
data_code  = data_1.status_code#查看状态码
data_request_headers = data_1.request.headers
data_text = data_1.text#查看正文,返回的响应正文,不论是什么方式,都可以用此种方式
data_json= data_1.json()#查看正文,返回的响应正文,是字典/json格式,可用此种方式
data_time = data_1.elapsed.total_seconds()#查看接口响应时间
print(data_headers)
int(data_code)
print(data_request_headers)
print(data_text)
print(data_json)
print(data_time)

查看cookies

  • 如果接口文档中没有明确的规定说,请求是json格式的,那么请求都是放在字典中的
  • cookies,向服务器表名请求是同一个账号发的
  • 一般来说,登录成功后会存在cookies
  • cookies的获取方式:直接用return返回值.cookies即可;因没有合适的网站,在此不做样例展示
  • cookies其实是一种 类字典的形式,可以用字典取值的方式进行取值
import requests

#登录数据
login='http://47.107.168.87:8080/futureloan/mvc/api/member/login'
login_data={'mobilephone':18688773467,'pwd':'123456'}
res = requests.post(url=login,data=login_data)
res_meg = res.text
cookies_mes = res.cookies
print(cookies_mes)#获取cookies
print(res_meg)

cookies的常见问题

  • 什么时候带cookies?
    • 答:如果是cookies+session的验证方式,用户登录成功后一般会返回cookies,接口需要验证登录权限的时候,headers中需要带cookies进行验证
  • text和json都能够获取结果,用哪个比较好?
    • 答:如果要取值的话,建议使用字典
  • 用户登录成功后带cookies的才能操作的请求,有另外一种方式来解决吗?
    • 答:可以直接封装session来解决
    • requests模块中封装了session模块,该模块可以自动管理session的会话信息,自动保存cookies到连接中,这样就不需要主动传递cookies了
#第一步:实例化session
#session = requests.Session()
#第二部:使用session发送接口请求,后续一旦都是同一个session对象发送请求,那么这个session都会将所有的请求过程中产生的会话信息都保存在一session对象中,特别是cookies

- 使用session的方式请求,可以

将request写成一个类,支持两种请求

import requests

# class RequestHttp:#创建一个http请求的类

def http_request(url,param,mechod,cookie=None):
     if mechod=='get':
        res=requests.get(url,param,cookies=cookie)
     else:
        res=requests.post(url,param,cookies=cookie)
     return res

if __name__=='__main':
    #登录数据
    login='http://47.107.168.87:8080/futureloan/mvc/api/member/login'
    login_data={'mobilephone':18688773467,'pwd':'123456'}
    # 充值
    recharge='http://47.107.168.87:8080/futureloan/mvc/api/member/recharge'
    recharge_data={'mobilephone':18688773467,'amount':'1000'}

    #调用类
    # res_1=RequestHttp()
    res_login=http_request(login,login_data,'get')
    print('登录的结果是',res_login.json())
    print('-'*50)
    res_recharge=http_request(recharge,recharge_data,'post',cookie=res_login.cookies)
    print('充值的结果是',res_recharge.json())

json和jsonpath

json的定义

  • JSON(JavaScript Object Notation, JavaScript 对象表示法) 是一种轻量级的数据交换格式。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。

json的语法规则

    1. 数据在键值对中
    1. 多条数据由逗号分隔
    1. 花括号 {} 保存对象:例如{"name": "tom","age": "26"}
    1. 中括号 [] 保存数组:例如{"hobby": ["游戏", "音乐", "电影"]}
    1. JSON值的类型:
    • 数字(整数或浮点数)
    • 字符串(在双引号中)
    • 逻辑值(true 或 false)-- 与Python字典有区别
    • 数组(在中括号中)-- 与python列表类似
    • 对象(在大括号中)
    • null – 与Python也有区别 None
  • 重点注意!!! 标准的JSON中不能通过单引号包裹字符串,需要使用双引号
  • 例如
{
"name": "rose",
"age": 10,
"height": 180.5,
"isSingle": false,
"address": {
"provinces": "湖南省",
"city": "长沙"
},
"hobby": ["游戏", "音乐", "电影"],
"weight": null
}

jsonpath

  • jsonpath的运算符
运算符说明
$根节点 ~ 相当于xpath中/
.(单个英文点)获取子节点
… (两个英文点)在子孙节点中进行递归搜索 $…~ 相当于xpath里面//
*星号通配符,可以表示任何元素
[a,b]选择多个子节点 ~ 了解
[start:end]切片,区间为[start,end),左闭右开 ~ 了解
[?(过滤条件)]过滤器表达式,过滤条件结果必须是boolean类型,比如可以是比较表达式或者逻辑表达式
@过滤器中处理当前节点,通常会和过滤器一起使用
  • python中的用法
import requests
import jsonpath
res = requests.get('http://mall.lemonban.com:8107/search/searchProdPage?
prodName=平板电脑')
result = jsonpath.jsonpath(res.json(),'$.records[*].prodId')
print(result)
  • 示例,以下是json文件
# json数据
{
  "data": {
    "page": 1,
    "size": 50,
    "source": "weibo,weixin,forum,insvideo,video,tv,news,app,pingmei,blog",
    "time": "1697472000~1697535034",
    "sort_of": "",
    "match_fields": [
      "content",
      {
        "content": "公司"
      },
      {
        "filters": [
          {
            "site_domain": " weixin"
          },
          {
            "site_name": "微信"
          },
          {
            "username": "fyk"
          }
        ]
      }
    ],
    "must_kw": "境外_1024",
    "title": {
      "site_domain": "weibo",
      "site_name": "微博",
      "username": "fyy"
    }
  }
}
  • 通过jsonpath获取代码
import jsonpath
import json
with open("data.json","r",encoding="utf-8") as f:
    data = json.loads(f.read())
    js_1 = jsonpath.jsonpath(data,"$.data") # $根节点,.代表子节点
    print("js_1",js_1)
    js_2 = jsonpath.jsonpath(data,"$..site_name") # $根节点,两个点代表根节点下面的所有节点
    print("js_2",js_2)
    js_3 = jsonpath.jsonpath(data,"$..filters")#相对路径写法
    print("js_3",js_3)
    js_4 = jsonpath.jsonpath(data,"$..filters[0:2]")#非子节点的切片得到列表之后切片
    print("js_4",js_4)
    js_5 = jsonpath.jsonpath(data,"$.filters[0:2]")#子节点的切片得到列表之后切片
    print("js_5",js_5)
    js_6 = jsonpath.jsonpath(data,"$.data.match_fields")#绝对路径写法
    print("js_6",js_6)
    js_7 = jsonpath.jsonpath(data,"$..filters[0].site_domain")#根据索引获取某个元素,然后根据key取值
    print("js_7",js_7)
    js_8 = jsonpath.jsonpath(data,"$..title[?(@.username=\"fyy\")]")#根据索引获取某个元素,然后根据key取值
    print("js_8",js_8)
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值