一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python接口自動化淺析數據驅動原理

Python接口自動化淺析數據驅動原理

2021-12-24 00:25軟件測試自動化測試 Python

這篇文章主要介紹了Python接口自動化淺析數據驅動原理,文中會詳細描述怎樣使用openpyxl模塊操作excel及結合ddt來實現數據驅動,有需要的朋友可以參考下

在上一篇Python接口自動化測試系列文章:Python接口自動化淺析登錄接口測試實戰,主要介紹接口概念、接口用例設計及登錄接口測試實戰。

以下主要介紹使用openpyxl模塊操作excel及結合ddt實現數據驅動

在此之前,我們已經實現了用unittest框架編寫測試用例,實現了請求接口的封裝,這樣雖然已經可以完成接口的自動化測試,但是其復用性并不高。

我們看到每個方法(測試用例)的代碼幾乎是一模一樣的,試想一下,在我們的測試場景中,

一個登錄接口有可能會有十幾條到幾十條測試用例,如果每組數據都編寫一個方法,

這樣將會有更多的重復項代碼,不僅執行效率不高,也不好維護。

接下來將會對框架進行優化,采用數據驅動方式:

  • 把測試數據用excel表格管理起來,代碼做封裝;
  • 用ddt來驅動測試,兩部分相互獨立。

一、openpyxl模塊

openpyxl模塊介紹

openpyxl是python第三方模塊,運用openpyxl庫可以進行excel的讀和寫。

在了解openpyxl模塊之前,我們需要先熟悉excel的結構,才能更好理解openpyxl是如何操作excel。

從外到內,首先是一個excel文件(名),打開excel之后,會看到底部有一個或多個sheet(工作簿),每個sheet里有很多單元格,總體來說,主要分為三個層級。

Python接口自動化淺析數據驅動原理

在opnepyxl里面,一個Excel文件對應著一個Workbook對象, 一個Sheet對應著一個Worksheet對象,而一個單元格對應著一個Cell對象。了解這些之后,對openpyxl是如何操作excel就比較清楚了。

openpyxl安裝

pip install openpyxl

openpyxl簡單使用

import openpyxl
 
if __name__ == "__main__":
    path = "F:/case/test_case.xlsx"
    # 讀取excel文件
    workbook = openpyxl.load_workbook(path)
    # 讀取所有sheet
    sheet = workbook.get_sheet_names()
    # 獲取某個sheet
    sheet = workbook[sheet[0]]
    # 獲取某個cell的值
    cell_val = sheet.cell(row=2, column=2).value
    print(cell_val)

以上僅介紹openpyxl常用的語法,有興趣了解更多內容可自行百度擴展。

二、Excel用例管理

在項目下,新建一個文件夾:data,文件夾下新建一個cases.xlsx文件,用來存放測試用例。

Python接口自動化淺析數據驅動原理

以下,是一個簡單的登錄測試用例設計模板:

Python接口自動化淺析數據驅動原理

可以根據該表格生成實際結果,并將測試結果寫入(Pass、Fail)表格。

公眾號后臺回復:接口測試用例模板,可以獲取完整接口測試用例Excle模板。

既然有了用例模板,我們就開始從用openpyxl模塊對excel讀寫數據。

如下,在common文件夾下,新建excel_handle.py,用于封裝操作excel的類。

Python接口自動化淺析數據驅動原理

excel_handle.py

import openpyxl
class ExcelHandler:
    def __init__(self, file):
        self.file = file
    def open_excel(self, sheet_name):
        """打開Excel、獲取sheet"""
        wb = openpyxl.load_workbook(self.file)
        # 獲取sheet_name
        sheet = wb[sheet_name]
        return sheet
    def get_header(self, sheet_name):
        """獲取header(表頭)"""
        wb = self.open_excel(sheet_name)
        header = []
        # 遍歷第一行
        for i in wb[1]:
            # 將遍歷出來的表頭字段加入列表
            header.append(i.value)
        return header
    def read_excel(self, sheet_name):
        """讀取所有數據"""
        sheet = self.open_excel(sheet_name)
        rows = list(sheet.rows)
        data = []
        # 遍歷從第二行開始的每一行數據
        for row in rows[1:]:
            row_data = []
            # 遍歷每一行的每個單元格
            for cell in row:
                row_data.append(cell.value)
                # 通過zip函數將兩個列表合并成字典
                data_dict = dict(zip(self.get_header(sheet_name),row_data))
            data.append(data_dict)
        return data
    @staticmethod
    def write_excel(file, sheet_name, row, cloumn,data):
        """Excel寫入數據"""
        wb = openpyxl.load_workbook(file)
        sheet = wb[sheet_name]
        sheet.cell(row, cloumn).value = data
        wb.save(file)
        wb.close()
if __name__ == "__main__":
    # 以下為測試代碼
    excel = ExcelHandler("../data/cases.xlsx")
    data = excel.read_excel("login")

接下來結合ddt實現數據驅動,先簡單來介紹下ddt。

三、ddt介紹及使用

ddt介紹

  • 名稱:Data-Driven Tests,數據驅動測試
  • 作用:由外部數據集合來驅動測試用例的執行
  • 核心的思想:數據和測試代碼分離
  • 應用場景:一組外部數據來執行相同的操作
  • 優點:當測試數據發生大量變化的情況下,測試代碼可以保持不變
  • 實際項目:excel存儲測試數據,ddt讀取測試數據到單元測試框架(測試用例中)

補充:

所謂數據驅動,就是數據的改變從而驅動自動化測試的執行,最終引起測試結果的改變。說的直白些,就是參數化的應用。

ddt安裝

pip install ddt

ddt使用

要想知道ddt到底怎么使用,我們從ddt模塊源碼中提取出三個重要的函數ddt、unpack、data。

def ddt(cls):
    """
    Class decorator for subclasses of ``unittest.TestCase``.
    Apply this decorator to the test case class, and then
    decorate test methods with ``@data``.
    For each method decorated with ``@data``, this will effectively create as
    many methods as data items are passed as parameters to ``@data``.
    The names of the test methods follow the pattern
    ``original_test_name_{ordinal}_{data}``. ``ordinal`` is the position of the
    data argument, starting with 1.
    For data we use a string representation of the data value converted into a
    valid python identifier.  If ``data.__name__`` exists, we use that instead.
    For each method decorated with ``@file_data("test_data.json")``, the
    decorator will try to load the test_data.json file located relative
    to the python file containing the method that is decorated. It will,
    for each ``test_name`` key create as many methods in the list of values
    from the ``data`` key.
    """
    for name, func in list(cls.__dict__.items()):
        if hasattr(func, DATA_ATTR):
            for i, v in enumerate(getattr(func, DATA_ATTR)):
                test_name = mk_test_name(name, getattr(v, "__name__", v), i)
                test_data_docstring = _get_test_data_docstring(func, v)
                if hasattr(func, UNPACK_ATTR):
                    if isinstance(v, tuple) or isinstance(v, list):
                        add_test(
                            cls,
                            test_name,
                            test_data_docstring,
                            func,
                            *v
                        )
                    else:
                        # unpack dictionary
                        add_test(
                            cls,
                            test_name,
                            test_data_docstring,
                            func,
                            **v
                        )
                else:
                    add_test(cls, test_name, test_data_docstring, func, v)
            delattr(cls, name)
        elif hasattr(func, FILE_ATTR):
            file_attr = getattr(func, FILE_ATTR)
            process_file_data(cls, name, func, file_attr)
            delattr(cls, name)
    return cls
def unpack(func):
    """
    Method decorator to add unpack feature.
    """
    setattr(func, UNPACK_ATTR, True)
    return func
def data(*values):
    """
    Method decorator to add to your test methods.
    Should be added to methods of instances of ``unittest.TestCase``.
    """
    global index_len
    index_len = len(str(len(values)))
    return idata(values)

ddt:

裝飾類,也就是繼承自TestCase的類。

data:

裝飾測試方法。參數是一系列的值。

unpack:

傳遞的是復雜的數據結構時使用。比如使用元組或者列表,添加unpack之后,ddt會自動把元組或者列表對應到多個參數上,字典也可以這樣處理;當沒有加unpack時,方法的參數只能填一個。

知道了具體應用后,簡單來個小例子加深理解。

test_ddt.py

import unittest
import ddt
# 裝飾類
@ddt.ddt
class DdtDemo(unittest.TestCase):
    def setUp(self):
        pass
    def tearDown(self):
        pass
    
    # 裝飾方法
    @ddt.data(("15312344578", "12345678"), ("15387654321", "12345678"))
    @ddt.unpack
    def test_ddt(self, username,password):
        print(username,password)
if __name__ == "__main__":
    unittest.main(verbosity=2)

運行結果為:

Ran 2 tests in 0.001s
OK
15312344578 12345678
15387654321 12345678

上面的例子是為了加深理解,接下來介紹excel結合ddt實現數據驅動,優化之前的test_login.py模塊。

test_login.py

import unittest
from common.requests_handler import RequestsHandler
from common.excel_handler import ExcelHandler
import ddt
import json
@ddt.ddt
class TestLogin(unittest.TestCase):
    # 讀取excel中的數據
    excel = ExcelHandler("../data/cases.xlsx")
    case_data = excel.read_excel("login")
    print(case_data)
    def setUp(self):
        # 請求類實例化
        self.req = RequestsHandler()
    def tearDown(self):
        # 關閉session管理器
        self.req.close_session()
    @ddt.data(*case_data)
    def test_login_success(self,items):
        # 請求接口
        res = self.req.visit(method=items["method"],url=items["url"],json=json.loads(items["payload"]),
                             headers=json.loads(items["headers"]))
        try:
            # 斷言:預期結果與實際結果對比
            self.assertEqual(res["code"], items["expected_result"])
            result = "Pass"
        except AssertionError as e:
            result = "Fail"
            raise e
        finally:
            # 將響應的狀態碼,寫到excel的第9列,即寫入返回的狀態碼
            TestLogin.excel.write_excel("../data/cases.xlsx", "login", items["case_id"] + 1, 9, res["code"])
            # 如果斷言成功,則在第10行(測試結果)寫入Pass,否則,寫入Fail
            TestLogin.excel.write_excel("../data/cases.xlsx", "login", items["case_id"] + 1, 10, result)
if __name__ == "__main__":
    unittest.main()

整體流程如下圖:

Python接口自動化淺析數據驅動原理

到此這篇關于Python接口自動化淺析數據驅動原理的文章就介紹到這了,更多相關Python接口自動化數據驅動內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/ZangKang1/article/details/119488376

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产美女久久精品香蕉69 | 4438成人网 | ass亚洲熟妇毛茸茸pics | 日本热妇 | 免费网站国产 | 无删减影视免费观看 | 天天色综合久久 | 男人天堂久久 | 4hc44四虎www在线影院男同 | 亚洲冬月枫中文字幕在线看 | 国产精品激情综合久久 | 美女扒开肌肌让男人桶 | 好男人社区www影院在线观看 | 成人在线视频在线观看 | 美女靠逼免费视频 | 国产一区在线免费观看 | 91久久国产青草亚洲 | 青草视频在线观看视频 | 国产精品福利在线观看秒播 | 亚洲成综合人影院在院播放 | 午夜影院一区二区三区 | 国产成+人+综合+亚洲不卡 | 国产卡一卡二卡3卡乱码免费 | 久久国产伦子伦精品 | 亚洲大片在线观看 | 91尤物在线 | 亚洲欧美色综合图小说 | 爽好舒服快想要免费看 | a级黄色网 | 欧美性色欧美a在线播放 | 国产精品亚洲片夜色在线 | 欧美 亚洲 一区 | 叛佛 作者满栀小说免费阅读 | 男女刺激高清视频在线观看 | 国产成人刺激视频在线观看 | 欧美性一区二区三区 | 精品操 | 温柔校草高h | 成人福利在线视频免费观看 | 91综合精品网站久久 | 国产精品1 |