接口自动化
一、环境准备
1、接口文档
2、编程语言
3、第三方接口库
口诀1:params参数,传入的是字典,自动编码为表单。
口诀2:data参数,传入的是字典,自动编码为表单。
口诀3:data参数,传入的是字符串,按原格式直接发布出去。
口诀4:json参数,传入的是字典,自动编码为json字符串。
口诀5:json参数,传入的是字符串,添加双引号后,按原格式直接发布出去。
口诀6:headers参数,传递的是字典格式
口诀7:如果接口文档要求content-type为表单,心里默念:key和value间用(=等号),参数之间用(&连接符)
口诀8:如果接口文档要求content-type为json字符串,心里默念:key和value间用(:冒号),参数之间用(&连接符)
口诀9:其实json参数完全可以用data参数替代的。json参数做了一个把字典格式转换为json字符串的操作
即: data=json.dumps(dictPayload) 等同于 json=dictPayload
params 参数(查询字符串参数)
传递的是字典,自动编码为表单
data 参数(消息体参数)
传递的是字典,自动编码为表单
传递的是字符串,直接发布出去
json参数(消息体参数)
传递的是字典,自动编码为json字符串,相当于:json.dumps(dict)
传递的是字符串,加双号后直接发布出去
headers参数(请求头参数)
传递字典格式即可
cookies参数(请求头中的cookies参数)
传递字典格式即可
# json.dumps() 将字典转化为字符串
# json.loads() 将字符串转化为字典
二、实战实例基础
1、接口文档查看
2、python代码实例
# allchips_login
import requests
requests.packages.urllib3.disable_warnings() # 忽略警告 针对https
# url
url = 'https://passport.allchips.com/ucenter/userLogin'
# 请求头
header = {'Content-Type': 'application/json'}
# data
data = '{"account":"18062351647","password":"IKIOq71IpGfwG7zSV8P4P2zxPwogmQd44fcYiK2owYRoawCu8xnFtXB3Ybo6/U8U5N2Sc2+vpCw8oCTQVi49b4yyR2jHWaFDGMRahUkHuBF2QGpChVCQQ492PgvQbH9ec/rn/QkNtoES7T42HOMO9dhyodYJlLFU01d5N9eCI7U=","loginWay":10,"loginSource":10,"captchaPojo":null}'
resp = requests.post(url= url,data= data,headers = header)
print(resp.text) # 查看响应数据
print(resp.status_code) # 返回状态码
print(resp.headers) # 查看响应头
3、fiddler工具辅助验证请求
- 查看请求地址
- 查看请求方式
- 查看请求参数
- 查看请求头
4、requests库接口自动化常用技能和参数
-
requests常见参数:
- url 参数:传入的是字符串,请求地址
- data参数:传入的是字典,自动编码为表单,常用于表单格式
- json参数:传入的是字典,自动编码为json字符串
- params参数:传入的是字典,自动编码为表单
- headers参数:传递的是字典格式,传递请求头
- file参数:传递的是字典格式,一般使用在文件上传
- cookies参数:传递的是字典格式,传递cookie
-
response响应参数:
- re.text:获取响应文本信息,返回字符串
- res.json:获取json数据信息,返回字典
- res.headers:获取响应头
- res.status_code:获取响应状态码
- res.cookies:获取cookie信息
- res.request.headers:获取请求头
- res.request.body:获取请求体
-
代码实例:
import requests
# 请求URL
url = ''
# 请求头
headers = ''
# 请求参数
data = ''
# 打印
res = requests.post(url= '',data= '',headers='' )
print(res.text) # 返回参数,是字符串
print(res.status_code) # 返回状态码
print(res.cookies) # 返回cookies
print(res.elapsed.total_seconds()) # 接口请求完成时间
print(res.url) # 打印请求url
print(res.headers) # 打印返回头
print(res.request.headers) # 打印请求头
print(res.headers) # 查看响应头
print(res.request.body) # 打印请求体
三、Excel测试用例
1、Excel测试用例读取
import xlrd
# 1、读取Excel测试用例
exceldir = 'F:\松勤VIP\松勤-教管系统接口测试用例-v1.4.xls'
# 打开Excel
workbook = xlrd.open_workbook(exceldir)
# print(workbook.sheet_names())
# 读取sheet页
worksheet = workbook.sheet_by_name('1-登录接口')
# print(worksheet)
# 读取一行
rows = worksheet.row_values(1)
# print(rows)
# 读取一列,读列其实就是读取单元格内的数据
cell = worksheet.cell_value(1,6)
print(cell)
# 读取单元格
cellData = worksheet.cell(1,5).value
print(cellData)
# 封装后
import xlrd
# from configs.config import HOST
def get_excel(sheetname,startRow,endRow):
reslist = []
# Excel的路径
exceldir = 'F:\studywork\data\教管系统接口测试用例.xls'
# 打开Excel对象,--formatting_info=True,保持样式
workbook = xlrd.open_workbook(exceldir,formatting_info=True)
# 获取某一个指定的表
worksheet = workbook.sheet_by_name(sheetname)
# 获取单元格---返回的是字符串---cell(行号、列号),都是从0开始
for one in range(startRow-1,endRow): # 注意这里循环的是行数
responsebody = worksheet.cell(one,9).value # 请求参数
requestdata = worksheet.cell(one,11).value # 响应数据
reslist.append((responsebody,requestdata))
return reslist
if __name__ == '__main__':
for one in get_excel('登录模块',2,7):
print(one)
2、接口请求代码构建
import requests
url = 'http://localhost/api/mgr/loginReq'
# heard = {
# "Content-Type":"application/x-www-form-urlencoded"
# }
data = {
"username": "auto",
"password": "sdfsdfsdf"
}
resp = requests.post(url,data)
# resp = requests.post(url,data,heard) # requests 可以忽略请求表头的类型
print(resp.text)
print(resp.status_code)
3、测试结果写入到Excel
# 3、测试结果写入到Excel
from xlutils.copy import copy
workbooknew = copy(workbook)
worksheetnew = workbooknew.get_sheet(0)
for one in range(0,len(data)):
login = Login()
res = login.login(data[one][0]) # 响应参数
resp = json.loads(data[one][1]) # Excel中的json参数
if res == resp:
print("pass:通过")
worksheetnew.write(one+1,12,'pass') #(行号、列号、字符串内容)
else:
print("false:失败")
worksheetnew.write(one + 1, 12, 'false')
workbooknew.save('F:\studywork\data\教管系统接口测试用例res.xls')
4、完整的接口自动化代码
import json
import xlrd
# 1、读取Excel测试用例
exceldir = 'F:\studywork\data\教管系统接口测试用例.xls'
# 打开Excel
workbook = xlrd.open_workbook(exceldir,formatting_info=True)
# 读取sheet页
worksheet = workbook.sheet_by_name('登录模块')
# 读取一行
rows = worksheet.row_values(1)
# 读取一列,读列其实就是读取单元格内的数据
# cell = worksheet.cell_value(1,6)
# 读取单元格数据
# cellurl= worksheet.cell(1,5).value
data = []
for one in range(1,7):
cellurl = worksheet.cell(one,9).value # 从Excel里面读取每一行的请求参数
celldata = worksheet.cell(one, 11).value # 从Excel里面读取每一行的响应结果
data.append((cellurl,celldata))
# 2、构建接口请求
from lib.usb_login import Login
for one in data:
login = Login()
res = login.login(one[0]) # 响应参数
resp = json.loads(one[1])
# print(res)
# print(resp)
# if res == resp:
# print("pass:通过")
# else:
# print("false:失败")
# 3、测试结果写入到Excel
from xlutils.copy import copy
workbooknew = copy(workbook)
worksheetnew = workbooknew.get_sheet(0)
for one in range(0,len(data)):
login = Login()
res = login.login(data[one][0]) # 响应参数
resp = json.loads(data[one][1]) # Excel中的json参数
if res == resp:
print("pass:通过")
worksheetnew.write(one+1,12,'pass') #(行号、列号、字符串内容)
else:
print("false:失败")
worksheetnew.write(one + 1, 12, 'false')
workbooknew.save('F:\studywork\data\教管系统接口测试用例res.xls')
四、Excel测试用例自动化操作流程
- 读取Excel用例
- 构建接口请求
- 测试结果写入Excel
五、实战实例Excel测试用例
1、登录代码封装
from configs.config import HOST
import requests
import json
class Login:
def __init__(self):
self.url = f'{HOST}/api/mgr/loginReq'
def login(self,indata):
payload = json.loads(indata)
self.resp = requests.post(self.url,payload)
# self.cookies = self.resp.cookies
# print(self.cookies)
# print(self.resp.json())
return self.resp.json()
# return self.resp.json()
def get_cookie(self):
self.cookies = self.resp.cookies
# print(self.cookies)
return self.cookies
if __name__ == '__main__':
# print(Login().login({"username": "auto","password": "sdfsdfsdf"}))
# print(Login().get_cookie())
login = Login()
data = {"username": "auto","password": "sdfsdfsdf"}
payload = json.dumps(data)
# print(type(login.login(payload)))
print(login.login(payload))
# print(login.get_cookie())
2、读取Excel代码封装
import xlrd
from xlutils.copy import copy
def get_excel(sheetname,startRow,endRow):
reslist = []
# Excel的路径
exceldir = 'F:\studywork\data\教管系统接口测试用例.xls'
# 打开Excel对象,--formatting_info=True,保持样式
workbook = xlrd.open_workbook(exceldir,formatting_info=True)
# 获取某一个指定的表
worksheet = workbook.sheet_by_name(sheetname)
# 获取单元格---返回的是字符串---cell(行号、列号),都是从0开始
for one in range(startRow-1,endRow): # 注意这里循环的是行数
responsebody = worksheet.cell(one,9).value # 请求参数
requestdata = worksheet.cell(one,11).value # 响应数据
# reslist.append([responsebody,requestdata]) # 这里可以在添加到列表前,转换成任意数据类型
reslist.append((responsebody,requestdata)) # 这里可以在添加到列表前,转换成任意数据类型
return reslist
def excel_new():
exceldir = 'F:\studywork\data\教管系统接口测试用例.xls'
# 打开Excel
workbook = xlrd.open_workbook(exceldir,formatting_info=True) #True保留Excel的原格式
workbooknew = copy(workbook)
worksheetnew = workbooknew.get_sheet(0)
return workbooknew,worksheetnew
if __name__ == '__main__':
exc = get_excel('登录模块',2,7)
for one in exc:
# print(type(exc))
# print(one)
print(one[0])
print(type(one[0]))
3、调用登录代码和Excel代码
import json
# 1、读取Excle测试用例数据
from Excel_study.getExceldata import get_excel
data = get_excel('登录模块',2,7)
# 2、构建接口对应请求
from lib.usb_login import Login
for one in data:
login = Login()
resp =login.login(one[0])
res = json.loads(one[1])
# print(res)
# 比较预期结果和实际结果
# if resp == res:
# print('pass')
# else:
# print('false')
# 3、写入结果
from Excel_study.getExceldata import excel_new
workbooknew,worksheetnew = excel_new()
for one in range(0,len(data)):
login = Login()
res = login.login(data[one][0]) # 响应参数
resp = json.loads(data[one][1]) # Excel中的json参数
if res == resp:
print("pass:通过")
worksheetnew.write(one+1,12,'pass') #(行号、列号、字符串内容)
else:
print("false:失败")
worksheetnew.write(one+1,12, 'false')
workbooknew.save('F:\studywork\data\教管系统接口测试用例res.xls')
六、有坑的代码逻辑注意点:
1、from表单data参数和json参数
- json.dumps()函数是将字典转化为字符串,json.dumps(字典)
- json.loads()函数是将字符串转化成字典,json.loads(json格式)
- json字典形式,其实是字符串
mport json
import requests
# 登录
def login():
url = 'http://localhost/api/mgr/loginReq'
data = {
"username": "auto",
"password": "sdfsdfsdf"
}
resp = requests.post(url,data)
# print(resp.json())
cookies = resp.cookies # 获取cookies
return cookies
#封装参数
def get_data():
data = {
"name":"初中化学1235",
"desc":"初中化学课程",
"display_idx":"4"
}
return json.dumps(data) #json.dumps()函数是将字典转化为字符串
# 新增课程
def add_kechen():
url = "http://localhost/api/mgr/sq_mgr/"
data = {
"action":"add_course",
"data": get_data() # 这里已经是字符串等同于字典嵌套
}
resp = requests.post(url=url, data =data,cookies = login())
print(resp.status_code)
print(resp.text)
print(resp.json())
# return resp.json()
add_kechen()
2、cookie传参两种方法
import json
import requests
# 登录
url = 'http://localhost/api/mgr/loginReq'
data = {
"username": "auto",
"password": "sdfsdfsdf"
}
resp = requests.post(url,data)
print(resp.text)
print(resp.json())
print(resp.status_code)
# # cookies = resp.headers['Set-Cookie'] # 反正不能从响应头里面去取cookies
# cookies = resp.headers
# 方案一、原生态cookie,第一种取cookie的方法;如果后续的接口直接使用这个cookie,不增加其他参数
cookies = resp.cookies
print(cookies)
#方案二、如果后续的接口需要使用这个cookie,在增加其他参数认证,怎么办?重新封装cookies
cookies1 = resp.cookies['sessionid']
print(cookies1)
print(type(cookies1))
3、封装代码,注意请求参数格式
from configs.config import HOST
import requests
import json
class Login:
def __init__(self):
self.url = f'{HOST}/api/mgr/loginReq'
def login(self,indata):
# indata = json.loads(indata)
payload = json.loads(indata)
# self.resp = requests.post(self.url,indata)
self.resp = requests.post(self.url,payload)
# self.cookies = self.resp.cookies
# print(self.cookies)
# print(self.resp.json())
return self.resp.json()
# return self.resp.json()
def get_cookie(self):
self.cookies = self.resp.cookies
# print(self.cookies)
return self.cookies
if __name__ == '__main__':
# print(Login().login({"username": "auto","password": "sdfsdfsdf"}))
# print(Login().get_cookie())
login = Login()
# data = {"username": "auto","password": "sdfsdfsdf"}
data = '{"username": "auto", "password": "sdfsdfsdf"}'
print(type(login.login(data)))
print(login.login(data))
# print(login.get_cookie())
import xlrd
# from configs.config import HOST
def get_excel(sheetname,startRow,endRow):
reslist = []
# Excel的路径
exceldir = 'F:\studywork\data\教管系统接口测试用例.xls'
# 打开Excel对象,--formatting_info=True,保持样式
workbook = xlrd.open_workbook(exceldir,formatting_info=True)
# 获取某一个指定的表
worksheet = workbook.sheet_by_name(sheetname)
# 获取单元格---返回的是字符串---cell(行号、列号),都是从0开始
for one in range(startRow-1,endRow): # 注意这里循环的是行数
responsebody = worksheet.cell(one,9).value # 请求参数
requestdata = worksheet.cell(one,11).value # 响应数据
# reslist.append([responsebody,requestdata]) # 这里可以在添加到列表前,转换成任意数据类型
reslist.append((responsebody,requestdata)) # 这里可以在添加到列表前,转换成任意数据类型
return reslist
if __name__ == '__main__':
exc = get_excel('登录模块',2,7)
for one in exc:
# print(type(exc))
# print(one)
print(one[0])
print(type(one[0]))
# 1、读取Excle测试用例数据
from Excel_study.getExceldata import get_excel
data = get_excel('登录模块',2,7)
# 2、构建接口对应请求
from lib.usb_login import Login
for one in data:
login = Login()
print(login.login(one[0]))
4、请求参数格式
import requests
import json
url = 'https://www.allchips.com/ucenter/api/users/createUserOnlineInquiry'
data = {"place":"大陆","inquiryList":[{"partName":"AMS1117-3.3","brandName":"","amount":1,"delivery":1,"price":1}],"userName":"15968689559","userPhone":"15968689557","userEmail":"","userWeChat":"","remark":"请忽略价格、交期、目标价格内容(用户从首页快捷提交未单独填写),请已实际线下联系询价目内容为准。"}
# 传参为json格式的转换方法一:
# resp = requests.post(url,json=data)
# 传参为json格式的转换方法二:
payload = json.dumps(data)
resp = requests.post(url,data=payload)
print(resp.json())
七、pytest框架
1、概述:
- 简单灵活,容易上手,文档丰富;
- 支持参数化,可以细粒度地控制要测试的测试用例;
- 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests);
- pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等;
- 测试用例的skip和xfail处理;
- 可以很好的和CI工具结合,例如jenkins
2、安装和编写规则
- pip install pytest
- 测试文件以test_开头(以_test结尾也可以)
- 测试类以Test开头,并且不能带有 init 方法
- 测试函数以test_开头
- 断言使用基本的assert即可
# -*- coding:utf-8 -*-
import pytest
@pytest.fixture(scope='function')
def setup_function(request):
def teardown_function():
print("teardown_function called.")
request.addfinalizer(teardown_function) # 此内嵌函数做teardown工作
print('setup_function called.')
@pytest.fixture(scope='module')
def setup_module(request):
def teardown_module():
print("teardown_module called.")
request.addfinalizer(teardown_module)
print('setup_module called.')
@pytest.mark.website
def test_1(setup_function):
print('Test_1 called.')
def test_2(setup_module):
print('Test_2 called.')
def test_3(setup_module):
print('Test_3 called.')
assert 2==1+1 # 通过assert断言确认测试结果是否符合预期
八、allure测试报告