目錄
準備工作
框架目錄
base:請求方法
data:存放數據
utils:操作方法
log:日誌
report:存放測試報告
tests:測試主程序
common:公共方法
封裝請求方法
在base目錄下創建requests.py文件 將常用請求方法 封裝
import requests
"""請求方法的封裝"""
class request:
def request(self,url,method='post',**kwargs):
'''
:param url: 請求地址
:param method: 請求方法
:param kwargs: 請求參數
:return:
'''
if method == 'post':
return requests.request(url=url,method=method,**kwargs)
elif method == 'get':
return request.request(url=url,method='get',**kwargs)
elif method == 'put':
return requests.request(url=url,method='put',**kwargs)
elif method == 'delete':
return request.request(url=url,method='delete',**kwargs)
def post(self,url,**kwargs):
return self.request(url=url,method='post',**kwargs)
def get(self,url,**kwargs):
return self.request(url=url,**kwargs)
def put(self,url,**kwargs):
return self.request(url=url,method='put',**kwargs)
def delete(self,url,**kwargs):
return self.request(url=url,method='delete',**kwargs)
封裝查找文件路徑公共
在base目錄下創建公共方法pubilc.py
import os
def dir_path(filepath='data',filename =None):
"""
:param filepath: 文件路徑
:param filename: 文件名稱
:return:
"""
return os.path.join(os.path.dirname(os.path.dirname(__file__)),filepath,filename)
對Excel操作方法進行封裝
在utils目錄下創建方法operationExcel.py文件
import xlrd
from common.pbulc import *
class ValueExcels:
caseID = 0
des = 1
url = 2
method = 3
data = 4
expect = 5
def CaseID(self):
return self.caseID
def description(self):
return self.des
def Url(self):
return self.url
def Method(self):
return self.method
def Data(self):
return self.data
def Expect(self):
return self.expect
class OperationExcel():
# valueExcels = ValueExcels()
def get_excel(self):
'''打開Excel文件'''
db = xlrd.open_workbook(dir_path(filename='data.xls'))
sheet = db.sheet_by_index(0)
return sheet
def get_row(self):
'''獲取Excel有多少行內容'''
return self.get_excel().nrows
def getValue(self,row,cel):
return self.get_excel().cell_value(row,cel)
def getCaseID(self,row):
'''獲取caseid列'''
return self.getValue(row,ValueExcels().CaseID())
def getURL(self,row):
return self.getValue(row,ValueExcels().Url())
def getdata(self,row):
return self.getValue(row,ValueExcels().Data())
def getmethod(self,row):
return self.getValue(row,ValueExcels().Method())
o = OperationExcel()
# print(o.getValue(1,ValueExcels().Url()))
print(o.getCaseID(1))
print(o.getURL(1))
print(o.getdata(1))
print(o.getmethod(1))
操作yaml文件
在utils目錄下創建操作yaml文件的方法
import yaml
from common.pbulc import *
class Operationyaml():
def dictyaml(self,filepath='data',filename='login.yaml'):
with open(dir_path(filepath=filepath,filename=filename),'r',encoding='utf-8') as f:
return yaml.safe_load(f)
o = Operationyaml()
print(o.dictyaml())
>>>{'data_01': {'phone': 11123412312, 'password': 123456}}
獲取yaml文件中的請求參數
修改utils文件夾下operationexcel文件 getdata方法取值方法
要獲取yaml文件中,如:data_01對應的value參數 要利用excel中data列的值 建立一個映射關係 獲取yaml文件中的參數
import xlrd
from common.pbulc import *
from utils.operationyaml import Operationyaml#導入yaml文件
class ValueExcels:
caseID = 0
des = 1
url = 2
method = 3
data = 4
expect = 5
def CaseID(self):
return self.caseID
def description(self):
return self.des
def Url(self):
return self.url
def Method(self):
return self.method
def Data(self):
return self.data
def Expect(self):
return self.expect
class OperationExcel(Operationyaml):#繼承Operationyaml類
def get_excel(self):
'''打開Excel文件'''
db = xlrd.open_workbook(dir_path(filename='data.xls'))
sheet = db.sheet_by_index(0)
return sheet
def get_row(self):
'''獲取Excel有多少行內容'''
return self.get_excel().nrows
def getValue(self,row,cel):
return self.get_excel().cell_value(row,cel)
def getCaseID(self,row):
'''獲取caseid列'''
return self.getValue(row,ValueExcels().CaseID())
def getURL(self,row):
return self.getValue(row,ValueExcels().Url())
def getdata(self,row):
# print(self.getValue(row, ValueExcels().Data()))
#在這裏 利用字典取值key:value的方式 將excel中key對應的yaml文件中的參數取到
return self.dictyaml()[self.getValue(row, ValueExcels().Data())]
def getmethod(self,row):
return self.getValue(row,ValueExcels().Method())
o = OperationExcel()
print(o.getdata(2))
>>>{"page":1}
測試主方法
tests目錄下創建test_API.py文件
把請求方法 操作文件的方法 全部導入 發送API請求
from base.mthod import request
from utils.operationExcel import OperationExcel
from utils.operationyaml import Operationyaml
import pytest
import json
class TestRun:
excel = OperationExcel()
obj = request()
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.excel.getURL(1),
data=self.excel.getdata(1)
)
print(r.json())
if __name__ == '__main__':
pytest.main('-v','test_API.py')
token的處理
在登錄請求獲取寫入文件
pubilc路徑下寫一個 寫入方法,寫入文件的目錄在默認的data路徑下 一會兒在登錄接口調用這個方法 將token寫入txt文件
def writetoken(contest):
"""
:param contest: 寫入內容的形參
:return:
"""
with open(dir_path(filename='token.txt'),'w') as f:
f.write(contest)
登錄接口調用文件寫入方法
from common.pbulc import *
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.url() + self.excel.getURL(1),
data=self.excel.getdata(1)
)
writetoken(json.dumps({"token":r.json()['data']['token']}))
查找token.txt文件路徑
在utils目錄下創建readlinetoken.py文件
from common.pbulc import *
def dir_token():
db = dir_path("data",'token.txt')
return db
def get_token():
file =open(dir_token(),'r')
token = file.readline()
file.close()
return token
在其他接口請求中使用token
from base.mthod import request
from utils.operationExcel import OperationExcel
from utils.operationyaml import Operationyaml
from utils.readlinetoken import get_token #導入查找token文件路徑方法
import pytest
import json
class TestRun:
excel = OperationExcel()
obj = request()
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.excel.getURL(1),
data=self.excel.getdata(1)
)
print(r.json())
writetoken(json.dumps({"token":r.json()['data']['token']}))
def test_YLMY_info(self):
"""我的"""
r = self.obj.post(
url=self.excel.getURL(2),
headers=json.loads(get_token()) #拼接headers
)
print(json.dumps(r.json(),indent=True,ensure_ascii=False))
if __name__ == '__main__':
pytest.main('-v','test_API.py')
斷言
在Excel表期望結果列中寫入結果與返回數據進行對比
在excel表中第一行預期結果中寫入msg對應的登錄成功 然後寫斷言
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.url() + self.excel.getURL(1),
data=self.excel.getdata(1)
)
assert self.excel.getexpect(row=1) in json.dumps(r.json(),ensure_ascii=False)
writetoken(json.dumps({"token":r.json()['data']['token']}))
這個斷言在每個接口中都會使用 所以封裝成一個方法 方便調用
def result(self,r,row):
"""
:param r: 實際結果
:param row:預期結果所在行
:return:斷言方法
"""
assert r.status_code == 200
assert self.excel.getexpect(row=row) in json.dumps(r.json(),ensure_ascii=False)
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.url() + self.excel.getURL(1),
data=self.excel.getdata(1)
)
# assert self.excel.getexpect(row=1) in json.dumps(r.json(),ensure_ascii=False)
self.result(r=r,row=1)#調用result斷言方法
writetoken(json.dumps({"token":r.json()['data']['token']}))
URL路徑分離
測試環境和生產環境只是域名 不同 後面的路徑都是相同的所以 在測試後測試環境後 在線上環境測試還要改域名 太麻煩 現在把excel表裏的域名 分離出來 放到一個公共方法裏 這樣在測試和正式環境 切換時 就只需要改一個就可以了
在操作operationexcel.py 文件中的geturl方法中 修改url獲取方法 把前面的域名和excel表中的路徑拼接起來
def getURL(self,row):
url = "http://127.0.0.1:5000" + self.getValue(row,ValueExcels().Url())
return url
# return self.getValue(row,ValueExcels().Url())
主方法不用改變 直接請求 這樣切換測試環境時 只需要改一次就可以了
def test_YLMY_login(self):
"""登錄"""
r = self.obj.post(
url=self.excel.getURL(1),
data=self.excel.getdata(1)
)
# assert self.excel.getexpect(row=1) in json.dumps(r.json(),ensure_ascii=False)
self.result(r=r,row=1)
writetoken(json.dumps({"token":r.json()['data']['token']}))
請求參數化
一個頁面的接口有很多個page頁 要測試 又不可能封裝好幾個用例 這樣可以將page重構成動態的
用更改字典k值的方式 將參數構造成動態的
from utils.operationExcel import OperationExcel
excel= OperationExcel()
def getpage(page):
dict1= excel.getdata(3)
dict1['page']=page
return dict1
導入上面的操作函數 在data參數上調用 然後傳入什麼參數就是什麼參數了
def test_YLMY_index(self):
"""首頁"""
r =self.obj.post(
url=self.excel.getURL(3),
data = getpage(2)
)
print(p)
print(r.status_code)
我想一次測試完page1到page5可以把參數放到列表裏 然後for循環傳入即可
ef test_YLMY_index(self):
"""首頁"""
page = [1,2,3,4,5]
for p in page:
r =self.obj.post(
url=self.excel.getURL(3),
data = getpage(p)
)
print(p)
print(r.status_code)
測試報告
Allure生成HTNL測試報告
配置工作:
1、下載地址:http://allure.qatools.ru/
2、下載完成解壓後將bin目錄的路徑添加到path環境變量中
3、DOS命令輸入 allure驗證是否完成 如果沒有報錯 說明沒問題
4、輸入 pip install allure-pytest 安裝這個庫
生成在線測試報告
執行測試 並使用Allure偵聽器在測試執行期間收集結果 --alluredir 提供存儲結果的路徑
pytest -v test_API.py --alluredir=/report
打開測試報告
allure serve /report
測試報告打開效果
同一個網段下的設備輸入本機ip端口號也能訪問