接口自動化
一、環境准備
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測試報告