API測試框架設計---基於Pytest

準備工作

框架目錄

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端口號也能訪問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章