最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python接口自動(dòng)化淺析數(shù)據(jù)驅(qū)動(dòng)原理

 更新時(shí)間:2021年08月25日 11:23:24   作者:軟件測(cè)試自動(dòng)化測(cè)試  
這篇文章主要介紹了Python接口自動(dòng)化淺析數(shù)據(jù)驅(qū)動(dòng)原理,文中會(huì)詳細(xì)描述怎樣使用openpyxl模塊操作excel及結(jié)合ddt來(lái)實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng),有需要的朋友可以參考下

在上一篇Python接口自動(dòng)化測(cè)試系列文章:Python接口自動(dòng)化淺析登錄接口測(cè)試實(shí)戰(zhàn),主要介紹接口概念、接口用例設(shè)計(jì)及登錄接口測(cè)試實(shí)戰(zhàn)。

以下主要介紹使用openpyxl模塊操作excel及結(jié)合ddt實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)。

在此之前,我們已經(jīng)實(shí)現(xiàn)了用unittest框架編寫測(cè)試用例,實(shí)現(xiàn)了請(qǐng)求接口的封裝,這樣雖然已經(jīng)可以完成接口的自動(dòng)化測(cè)試,但是其復(fù)用性并不高。

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

一個(gè)登錄接口有可能會(huì)有十幾條到幾十條測(cè)試用例,如果每組數(shù)據(jù)都編寫一個(gè)方法,

這樣將會(huì)有更多的重復(fù)項(xiàng)代碼,不僅執(zhí)行效率不高,也不好維護(hù)。

接下來(lái)將會(huì)對(duì)框架進(jìn)行優(yōu)化,采用數(shù)據(jù)驅(qū)動(dòng)方式:

  • 把測(cè)試數(shù)據(jù)用excel表格管理起來(lái),代碼做封裝;
  • 用ddt來(lái)驅(qū)動(dòng)測(cè)試,兩部分相互獨(dú)立。

一、openpyxl模塊

openpyxl模塊介紹

openpyxl是python第三方模塊,運(yùn)用openpyxl庫(kù)可以進(jìn)行excel的讀和寫。

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

從外到內(nèi),首先是一個(gè)excel文件(名),打開(kāi)excel之后,會(huì)看到底部有一個(gè)或多個(gè)sheet(工作簿),每個(gè)sheet里有很多單元格,總體來(lái)說(shuō),主要分為三個(gè)層級(jí)。

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

openpyxl安裝

pip install openpyxl

openpyxl簡(jiǎn)單使用

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

以上僅介紹openpyxl常用的語(yǔ)法,有興趣了解更多內(nèi)容可自行百度擴(kuò)展。

二、Excel用例管理

在項(xiàng)目下,新建一個(gè)文件夾:data,文件夾下新建一個(gè)cases.xlsx文件,用來(lái)存放測(cè)試用例。

以下,是一個(gè)簡(jiǎn)單的登錄測(cè)試用例設(shè)計(jì)模板:

可以根據(jù)該表格生成實(shí)際結(jié)果,并將測(cè)試結(jié)果寫入(Pass、Fail)表格。

公眾號(hào)后臺(tái)回復(fù):接口測(cè)試用例模板,可以獲取完整接口測(cè)試用例Excle模板。

既然有了用例模板,我們就開(kāi)始從用openpyxl模塊對(duì)excel讀寫數(shù)據(jù)。

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

excel_handle.py

import openpyxl
class ExcelHandler:
    def __init__(self, file):
        self.file = file
    def open_excel(self, sheet_name):
        """打開(kāi)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]:
            # 將遍歷出來(lái)的表頭字段加入列表
            header.append(i.value)
        return header
    def read_excel(self, sheet_name):
        """讀取所有數(shù)據(jù)"""
        sheet = self.open_excel(sheet_name)
        rows = list(sheet.rows)
        data = []
        # 遍歷從第二行開(kāi)始的每一行數(shù)據(jù)
        for row in rows[1:]:
            row_data = []
            # 遍歷每一行的每個(gè)單元格
            for cell in row:
                row_data.append(cell.value)
                # 通過(guò)zip函數(shù)將兩個(gè)列表合并成字典
                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寫入數(shù)據(jù)"""
        wb = openpyxl.load_workbook(file)
        sheet = wb[sheet_name]
        sheet.cell(row, cloumn).value = data
        wb.save(file)
        wb.close()
if __name__ == "__main__":
    # 以下為測(cè)試代碼
    excel = ExcelHandler('../data/cases.xlsx')
    data = excel.read_excel('login')

接下來(lái)結(jié)合ddt實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng),先簡(jiǎn)單來(lái)介紹下ddt。

三、ddt介紹及使用

ddt介紹

  • 名稱:Data-Driven Tests,數(shù)據(jù)驅(qū)動(dòng)測(cè)試
  • 作用:由外部數(shù)據(jù)集合來(lái)驅(qū)動(dòng)測(cè)試用例的執(zhí)行
  • 核心的思想:數(shù)據(jù)和測(cè)試代碼分離
  • 應(yīng)用場(chǎng)景:一組外部數(shù)據(jù)來(lái)執(zhí)行相同的操作
  • 優(yōu)點(diǎn):當(dāng)測(cè)試數(shù)據(jù)發(fā)生大量變化的情況下,測(cè)試代碼可以保持不變
  • 實(shí)際項(xiàng)目:excel存儲(chǔ)測(cè)試數(shù)據(jù),ddt讀取測(cè)試數(shù)據(jù)到單元測(cè)試框架(測(cè)試用例中)

補(bǔ)充:

所謂數(shù)據(jù)驅(qū)動(dòng),就是數(shù)據(jù)的改變從而驅(qū)動(dòng)自動(dòng)化測(cè)試的執(zhí)行,最終引起測(cè)試結(jié)果的改變。說(shuō)的直白些,就是參數(shù)化的應(yīng)用。

ddt安裝

pip install ddt

ddt使用

要想知道ddt到底怎么使用,我們從ddt模塊源碼中提取出三個(gè)重要的函數(shù)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:

裝飾測(cè)試方法。參數(shù)是一系列的值。

unpack:

傳遞的是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)時(shí)使用。比如使用元組或者列表,添加unpack之后,ddt會(huì)自動(dòng)把元組或者列表對(duì)應(yīng)到多個(gè)參數(shù)上,字典也可以這樣處理;當(dāng)沒(méi)有加unpack時(shí),方法的參數(shù)只能填一個(gè)。

知道了具體應(yīng)用后,簡(jiǎn)單來(lái)個(gè)小例子加深理解。

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)

運(yùn)行結(jié)果為:

Ran 2 tests in 0.001s
OK
15312344578 12345678
15387654321 12345678

上面的例子是為了加深理解,接下來(lái)介紹excel結(jié)合ddt實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng),優(yōu)化之前的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中的數(shù)據(jù)
    excel = ExcelHandler('../data/cases.xlsx')
    case_data = excel.read_excel('login')
    print(case_data)
    def setUp(self):
        # 請(qǐng)求類實(shí)例化
        self.req = RequestsHandler()
    def tearDown(self):
        # 關(guān)閉session管理器
        self.req.close_session()
    @ddt.data(*case_data)
    def test_login_success(self,items):
        # 請(qǐng)求接口
        res = self.req.visit(method=items['method'],url=items['url'],json=json.loads(items['payload']),
                             headers=json.loads(items['headers']))
        try:
            # 斷言:預(yù)期結(jié)果與實(shí)際結(jié)果對(duì)比
            self.assertEqual(res['code'], items['expected_result'])
            result = 'Pass'
        except AssertionError as e:
            result = 'Fail'
            raise e
        finally:
            # 將響應(yīng)的狀態(tài)碼,寫到excel的第9列,即寫入返回的狀態(tài)碼
            TestLogin.excel.write_excel("../data/cases.xlsx", 'login', items['case_id'] + 1, 9, res['code'])
            # 如果斷言成功,則在第10行(測(cè)試結(jié)果)寫入Pass,否則,寫入Fail
            TestLogin.excel.write_excel("../data/cases.xlsx", 'login', items['case_id'] + 1, 10, result)
if __name__ == '__main__':
    unittest.main()

整體流程如下圖:

到此這篇關(guān)于Python接口自動(dòng)化淺析數(shù)據(jù)驅(qū)動(dòng)原理的文章就介紹到這了,更多相關(guān)Python接口自動(dòng)化數(shù)據(jù)驅(qū)動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python設(shè)計(jì)模式之觀察者模式原理與用法詳解

    Python設(shè)計(jì)模式之觀察者模式原理與用法詳解

    這篇文章主要介紹了Python設(shè)計(jì)模式之觀察者模式,簡(jiǎn)單講述了觀察者模式的概念、原理并結(jié)合實(shí)例形式分析了Python實(shí)現(xiàn)與使用方法,需要的朋友可以參考下
    2019-01-01
  • Python爬蟲爬取微信朋友圈

    Python爬蟲爬取微信朋友圈

    這篇文章主要介紹了Python爬蟲爬取微信朋友圈的方法,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí)Python爬蟲,感興趣的朋友可以了解下
    2020-08-08
  • 淺談python寫入大量文件的問(wèn)題

    淺談python寫入大量文件的問(wèn)題

    今天小編就為大家分享一篇淺談python寫入大量文件的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Python實(shí)現(xiàn)多線程下載文件的代碼實(shí)例

    Python實(shí)現(xiàn)多線程下載文件的代碼實(shí)例

    這篇文章主要介紹了Python實(shí)現(xiàn)多線程下載文件的代碼實(shí)例,需要的朋友可以參考下
    2014-06-06
  • Python分割指定頁(yè)數(shù)的pdf文件方法

    Python分割指定頁(yè)數(shù)的pdf文件方法

    今天小編就為大家分享一篇Python分割指定頁(yè)數(shù)的pdf文件方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • python使用psutil模塊獲取系統(tǒng)狀態(tài)

    python使用psutil模塊獲取系統(tǒng)狀態(tài)

    作為程序猿,大家可能都熟悉linux系統(tǒng)的基礎(chǔ)信息獲取方法都是通過(guò)shell來(lái)獲取,但是在python中,我們還可以使用psutil模塊來(lái)獲取系統(tǒng)信息。psutil模塊把shell查看系統(tǒng)基礎(chǔ)信息的功能都包裝了下,使用更加簡(jiǎn)單,功能豐富。
    2016-08-08
  • Python讀取配置文件-ConfigParser的二次封裝方法

    Python讀取配置文件-ConfigParser的二次封裝方法

    這篇文章主要介紹了Python讀取配置文件-ConfigParser的二次封裝方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解python opencv圖像混合算術(shù)運(yùn)算

    詳解python opencv圖像混合算術(shù)運(yùn)算

    這篇文章主要介紹了python opencv圖像混合算術(shù)運(yùn)算的相關(guān)知識(shí),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • Python語(yǔ)言的12個(gè)基礎(chǔ)知識(shí)點(diǎn)小結(jié)

    Python語(yǔ)言的12個(gè)基礎(chǔ)知識(shí)點(diǎn)小結(jié)

    這篇文章主要介紹了Python語(yǔ)言的12個(gè)基礎(chǔ)知識(shí)點(diǎn)小結(jié),包含正則表達(dá)式替換、遍歷目錄方法、列表按列排序、去重、字典排序等,需要的朋友可以參考下
    2014-07-07
  • python生成不重復(fù)隨機(jī)數(shù)和對(duì)list亂序的解決方法

    python生成不重復(fù)隨機(jī)數(shù)和對(duì)list亂序的解決方法

    下面小編就為大家分享一篇python生成不重復(fù)隨機(jī)數(shù)和對(duì)list亂序的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04

最新評(píng)論

武山县| 广安市| 葫芦岛市| 宁城县| 清镇市| 陆河县| 顺平县| 阿鲁科尔沁旗| 长春市| 西平县| 台东县| 高要市| 琼结县| 青铜峡市| 昌都县| 镇沅| 门源| 甘德县| 元氏县| 新乐市| 页游| 新竹县| 保亭| 清原| 黄平县| 达尔| 姚安县| 保山市| 启东市| 贡觉县| 资溪县| 两当县| 临武县| 长春市| 高要市| 滨海县| 赤水市| 托克托县| 广河县| 长葛市| 同德县|