一、requests简介
requests用来发送http请求以及接受http响应的python第三方库,主要用于接口自动化测试。
- 安装:pip install requests
二、requests库常用的方法
- requests.get() url是接口地址,params用于传参
- requests.post() url是接口地址,data用于传参,json也用于传参
- data和json传参的区别只要是通过请求头Content-Type来区分。
- 请求:请求方式、请求路径、请求头、请求正文。
- Content-Type
•
• multipart/form-data 文件上传
• application/x-www-form-urlencoded 表单提交
• application/json
• application/xml
• application/javascript
• application/binary
• text/html
• data和json传参以及Content-Type的关系如下:
• data传参:
• 报文是dict类型,那么默认是Content-Type:applocation/x-www-form-urlencoded
• 报文是str类型,那么默认是Content-Type:text/plain
• json传参:报文可以是dict类型,默认是Context-Type:application/json
• 所以:
• data:可以传纯键值对的dict(非嵌套的),也可以传str格式。
• json:可以传任何形式的dict(包括嵌套的dict)
• json与dict转换:
• json.loads() 把json字符串转化成dict格式
• json.dumps() 把dict格式转化成json字符串
• requests.put()
• requests.delete()
• requests.request()可以发送所有类型的请求:get、post、put、delete
不管是get还是post还是put和delete,底层都是调用的requests.request()方法。
而requests.request()调的是session.request()方法。主要参数:
method, 请求方式
url, 请求路径
params=None, get方式传参
data=None, post方式传参
json=None, post方式传参
headers=None, 请求头
cookies=None, 请求cookie
files=None, 文件上传
三、requests模块返回的response对象详解
- response.json() 获得返回的字典格式的数据
- response.text 获得返回的字符串格式的数据
- response.content 获得返回的bytes格式的数据
- response.status_code 状态码
- response.reason 状态信息
- response.cookies cookies信息
- response.headers 响应头
- response.request.xxx 返回请求的数据,如:请求头、请求参数..
四、请求必须带请求头的接口,以及需要cookie鉴权和session鉴权的接口
90%以上的基于web的接口都有cookie鉴权。
两种解决方式:
1.使用cookie关联
2.使用session关联
requests.session().request() 使用同一个会话发起请求。
import json
import re
import requests
class TestRequest:
# 全局变量,类变量
access_token = ""
csrf_token = ""
php_cookie = ""
sess = requests.session()
# get请求:获取统一鉴权码token接口
def test_get_token(self):
url = "https://api.weixin.qq.com/cgi-bin/token"
data = {
"grant_type": "client_credential",
"appid": "wx7ff6c1d5ba45d17e",
"secret": "4b5fe134130b7c292d6a6c22f38b56d0"
}
res = requests.request(method="get", url=url, params=data)
print(res.json())
TestRequest.access_token = res.json()['access_token']
# post请求:编辑标签接口
def test_edit_flag(self):
url = "https://api.weixin.qq.com/cgi-bin/tags/update?access_token=" + TestRequest.access_token
data = {"tag": {"id": 101, "name": "广东人"}}
str_date = json.dumps(data)
res = requests.request(method="post", url=url, data=str_date)
print(res.json())
# 文件上传
def test_file_upload(self):
url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=" + TestRequest.access_token
data = {
"media": open(r"E:\developer\idea\workspace\autotest_pytest\image.png", "rb")
}
res = requests.request(method="post", url=url, files=data)
print(res.json())
# 访问首页接口
def test_start(self):
url = "http://47.107.116.139/phpwind/"
# res = requests.request(method="get", url=url)
# 通过sess请求,就不用cookies
res = TestRequest.sess.request(method="get", url=url)
# print(res.text)
# 正则提取提取鉴权码
# re.search("正则表达式",res.text)
obj = re.search('name="csrf_token" value="(.*?)"', res.text)
# 取匹配到的第1个值
print(obj.group(1))
TestRequest.csrf_token = obj.group(1)
# # 提取cookies
# TestRequest.php_cookie = res.cookies
def test_login(self):
url = "http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun"
data = {
"username": "xxx",
"password": "xxx",
"csrf_token": TestRequest.csrf_token, # 鉴权码,从首页获取
"backurl": "http://47.107.116.139/phpwind/",
"invite": ""
}
headers = {
"Accept": "application/json,text/javascript,/; q=0.01",
"X-Requested-With": "XMLHttpRequest"
}
# res = requests.request(method="post", url=url, data=data, headers=headers, cookies=TestRequest.php_cookie)
# 使用session请求
res = TestRequest.sess.request(method="post", url=url, data=data, headers=headers)
print(res.json())
if __name__ == '__main__':
TestRequest.test_get_token()
TestRequest.test_edit_flag()
TestRequest.test_file_upload()
TestRequest.test_start()
TestRequest.test_login()
四、接口自动化测试框架关于接口关联的封装
策略:去掉全局变量,用YAML文件代替保存。
yaml_util.py 操作yaml文件的工具模块。
# 对yaml操作的工具
# 读取
import os
import yaml
def read_yaml(key):
with open(os.getcwd() + "/extract.yaml", mode="r", encoding="utf-8") as f:
# FullLoader 全局加载
value = yaml.load(stream=f, Loader=yaml.FullLoader)
return value[key]
# 写入
def write_yaml(data):
# 以追加的模式打开,编码格式为utf-8
with open(os.getcwd() + "/extract.yaml", mode="a", encoding="utf-8") as f:
yaml.dump(data, stream=f, allow_unicode=True)
# 清空
def clean_yaml():
# 以追加的模式打开,编码格式为utf-8
with open(os.getcwd() + "/extract.yaml", mode="w", encoding="utf-8") as f:
f.truncate()