接口自動化測試的實現(xiàn)

最近接到一個接口自動化測試的case,并展開了一些調研工作,最后發(fā)現(xiàn)卖毁,使用pytest測試框架并以數(shù)據驅動的方式執(zhí)行測試用例羡藐,可以很好的實現(xiàn)自動化測試贩毕。這種方式最大的優(yōu)點在于后續(xù)進行用例維護的時候對已有的測試腳本影響很小。當然仆嗦,pytest還有以下其他優(yōu)點:

  1. 可以讓用戶寫出更為緊湊的測試套件辉阶;
  2. 涉及到的樣板代碼并不多,因此用戶能夠容易地編寫和理解各種測試瘩扼;
  3. 測試夾具(fixture)函數(shù)常被用來向測試函數(shù)添加某個參數(shù)谆甜,并返回不同的值。在pytest中集绰,可以通過使用一個fixture來模塊化另外一個规辱。同時也可以使用多個fixture,在無需重寫測試用例的情況下栽燕,將測試覆蓋到所有參數(shù)的組合罕袋;
  4. 可擴展性強改淑,pytest有許多實用的插件。例如:pytest-xdist可以在不使用其他測試器的情況下炫贤,被用于執(zhí)行并行測試溅固;pytest-rerunfailures可以在測試失敗后重新運行,而且運行次數(shù)和運行之間的延遲時間都是可以設置的兰珍;allure/pytest-html生成測試報告侍郭;

相比較其它的測試框架,比如Robot Framework(在創(chuàng)建自定義的HTML報告方面比較繁瑣掠河,頂多能用來生成xUnit格式的簡短報告)亮元、UniteTest/PyUnit(需要大量的樣板代碼),pytest更適合作為本次自動化測試的框架唠摹。

下面為大家詳細的介紹這種自動化測試的實現(xiàn)過程爆捞。

1 前期的準備工作

1.1 接口路徑表

根據接口文檔,將接口的地址和路徑以及請求方式記錄在excel表中勾拉,key:接口名稱煮甥,type:請求方式,value:接口路徑藕赞,第一行baseurl為基本路徑成肘,type不填。接口名稱建議與接口文檔中的接口名稱一致斧蜕,這樣方便檢查双霍。如果同一個接口有多種請求方式,需要重新填寫一行批销,type為相對應的請求方式洒闸。這樣記錄接口路徑和請求方式是為了方便后面的數(shù)據提取和處理。

1.2 測試用例表

測試用例表中主要記錄9列類型的數(shù)據均芽,測試模塊:將接口按照模塊進行劃分有利于問題的定位和數(shù)據的分類丘逸;

  • 測試模塊:將被測接口按照功能進行模塊劃分;
  • 用例編號:主要用于記錄用例的條數(shù)掀宋,建議按照模塊名稱進行命名鸣个,如:登錄模塊,用例編號為login_001,login_002布朦;
  • 用例標題:記錄測試的內容囤萤;
  • 前置條件:當被測接口需要其他接口的數(shù)據支撐時,在前置條件欄中填入需要的接口數(shù)據:如:login_001:token(login_001指用例編號是趴,token指該用例執(zhí)行后返回的響應參數(shù)中token字段的值)涛舍,前提條件是該接口用例在本條用例之前;
  • 測試步驟:方便于模塊用例的執(zhí)行唆途;
  • 請求接口:按照接口路徑表中key的命名填寫富雅,需要請求登錄接口時掸驱,就填寫上圖中表中key命名的登錄接口。請求頭部:當請求頭部中有特殊的參數(shù)時没佑,比如該接口需要身份驗證authorization字段毕贼,而該字段的數(shù)據來源于登錄接口返回的token,這種用例的請求頭部應該這樣填寫: Content-Type=application/json,Authorization=<token>蛤奢;
  • 請求數(shù)據:填寫測試用例的請求數(shù)據鬼癣,按照key=value的格式記錄,如果需要其他接口的返回數(shù)據啤贩,在前置條件中加入之后待秃,再填寫請求數(shù)據中需要的返回數(shù)據即可,如:username =admin,password=zxcvbnm,token=<token>痹屹;
  • 斷言:根據接口返回的數(shù)據進行斷言章郁,主要是驗證返回數(shù)據中的某個字段是否正確,也是按照key=value的格式進行填寫志衍;

2 目錄結構及運行流程

2.1 文件目錄結構

  • testcase文件夾:存放測試用例表暖庄;
  • api文件夾:存放接口路徑表;
  • common文件夾:common文件中存放通用的數(shù)據處理的腳本楼肪,如data.py和utlis.py(主要作用是將表中的數(shù)據進行處理培廓,后面會進行詳細的說明)、config.py(測試套件的基本配置)淹辞;
  • report文件夾:用于存放測試完成后生成的測試報告;
  • conftest.py:屬于pytest的一種全局公用的文件俘侠,一些通用的方法可以放在conftest.py中象缀;
  • pytest.ini:pytest的配置文件;

2.2 測試的運行流程

觸發(fā)自動化測試之后爷速,測試數(shù)據的提取與處理并不會使用到pytest框架央星,當把數(shù)據處理為測試套件后,按模塊分配給pytest進行執(zhí)行惫东,包括測試模塊莉给、http請求、斷言廉沮。所有模塊執(zhí)行完之后將測試結果體現(xiàn)在生成的測試報告report.html中颓遏。測試結束之后可以通過郵件或者釘釘機器人的方式通知測試或開發(fā)本次自動化測試的測試結果。

3 測試用例的實現(xiàn)過程

下面簡單介紹一下測試用例實現(xiàn)過程中部分腳本的作用滞时。

3.1 讀取excel表

使用xlrd庫讀取excel表中的內容叁幢,python中還有很多可以對excel的數(shù)據進行操作的庫,如:openpyxl坪稽、xlsxwriter曼玩;循環(huán)遍歷每一行的數(shù)據鳞骤,保存為列表并賦值給self.list_data。

# -*- coding: utf-8 -*-
import xlrd
class Excel(object):
    def __init__(self, file_name):
        # 讀取excel
        self.wb = xlrd.open_workbook(file_name)
        self.sh = self.wb.sheet_names()
        self.list_data = []

    def read(self):
        for sheet_name in self.sh:
            sheet = self.wb.sheet_by_name(sheet_name)
            rows = sheet.nrows
            for i in range(0, rows):
                rowvalues = sheet.row_values(i)
                self.list_data.append(rowvalues)

3.2 將數(shù)據格式化成測試套件

第一步將表格數(shù)據保存為列表后黍判,還不是我們需要的數(shù)據格式豫尽,這樣的數(shù)據列表不能直接使用,這里進行了一次數(shù)據的格式化顷帖。這里需要用到config.py中的case_header的配置美旧,將中文的標題換成英文,并作為字典的key值窟她。之后從第1個元素開始循環(huán)遍歷data陈症,將data中每個元素都以 [{'key1': 'value1', 'key2': 'value2'}, {}, {}, ...]的形式保存為list_dict_data并返回。

def data_to_dict(data):
    """
    :param data: data_list
    :return:
    """
    head = []
    list_dict_data = []
    for d in data[0]:
        d = case_header.get(d, d)
        head.append(d)
    for b in data[1:]:
        dict_data = {}
        for i in range(len(head)):
            if isinstance(b[i], str):
                dict_data[head[i]] = b[i].strip()
            else:
                dict_data[head[i]] = b[i]
        list_dict_data.append(dict_data)
    return list_dict_data
case_header = { 
    '測試模塊': 'module', 
    '用例編號': 'id', 
    '用例標題': 'title', 
    '前置條件': 'condition', 
    '測試步驟': 'step', 
    '請求接口': 'api', 
    '請求方式': 'method', 
    '請求頭部': 'headers', 
    '請求數(shù)據': 'data', 
    '斷言': 'assert', 
    '步驟結果': 'score' }

3.3 生成可執(zhí)行的測試套件

上一步已經將數(shù)據處理成了[{'key1': 'value1', 'key2': 'value2'}, {}, {}, ...]這樣的格式震糖,但是發(fā)現(xiàn)這樣的格式沒有將模塊中的用例整合到一起录肯,列表中每一個元素都是單獨的一條用例,這樣的話不利于用例的執(zhí)行吊说,所以论咏,對上一步返回的數(shù)據再進行一次處理。因為測試用例和接口路徑是保存在兩個excel表中的颁井,所以需要將兩個表的數(shù)據進行合并厅贪。首先將接口路徑表中的數(shù)據讀取出來并處理成需要的格式 {'key': {'type': 'value', 'url': 'value'}},之后按照測試步驟中的順序把測試用例保存在steps字典中雅宾。由于代碼過長养涮,下面只展示核心部分。

for d in data:
    # 將請求數(shù)據和斷言數(shù)據格式化
    for key in ('data', 'assert', 'headers'):
        if d[key].strip():
            test_data = dict()
            for i in d[key].split(','):
                i = i.split('=')
                test_data[i[0]] = i[1]
            d[key] = test_data
    if d['module'].strip():
        if testcase:
            testsuite.append(testcase)
            testcase = {}
        testcase['module'] = d['module']
        testcase['steps'] = []
    no = str(d['step']).strip()
    if no:
        step = {'no': str(int(d['step']))}
        for key in ('id', 'title', 'condition', 'api', 'headers', 'data', 'assert'):
            if key == 'api':
                step[key] = {'type': apis[d.get(key, '')]['type'],
                             'url': apis['baseurl']['url'] + apis[d.get(key, '')]['url']}
            else:
                step[key] = d.get(key, '')
        testcase['steps'].append(step)
if testcase:
    testsuite.append(testcase)

3.4 pytest執(zhí)行測試套件

將http請求封裝在了conftest.py中眉抬,使用pytest數(shù)據驅動的特點贯吓,在執(zhí)行測試文件test_login。py中不需要import就可以直接調用蜀变。這里只展示了發(fā)起post請求的代碼悄谐,其它類型的請求類似,pytest.fixture通過固定參數(shù)request傳遞數(shù)據库北。然后使用'標記'中的pytest.mark.parametrize進行參數(shù)化和數(shù)據驅動更靈活爬舰。在fixture中的方法里面準備測試數(shù)據和前置依賴方法,在測試方法中參數(shù)化寒瓦,測試方法調用準備數(shù)據和前置方法情屹。pytest.mark.parametrize('post_request', data, indirect=True),indirect=True是把post_request當作函數(shù)去執(zhí)行杂腰,data則是前面生成的模塊的測試用例屁商,其中包括了發(fā)起\http請求所需要的所有參數(shù)。

@pytest.fixture()
def post_request(request):
    data = request.param['data']
    header = request.param['headers']
    url = request.param['api']['url']
    no = request.param['no']
    logger.info(f'request: {data}')
    response = requests.request('POST', url=url, headers=header, data=json.dumps(data))
    logger.info(f'response: {response.json()}')
    return response, no
# -*- coding: UTF-8 -*-
import pytest
import allure
from common.data import module_data


class TestCase(object):

    @allure.feature('登錄')
    @pytest.mark.parametrize('post_request', module_data(module='登錄'), indirect=True)
    def test_login(self, post_request):
        response = post_request[0].json()
        no = int(post_request[1])
        assert response['msg'] == module_data(module='登錄')[no - 1]['assert']['msg']
def module_data(module):

    excel = Excel(file_path.parent / 'testcase/testcase.xlsx')
    excel.read()
    cases = excel.list_data
    test_suit = suite_cases(data_to_dict(cases))
    for _ in test_suit:
        if _['module'] == module:
            data = _['steps']
            return data

3.5 運行測試用例

可以在pytest.ini中配置執(zhí)行測試時的一些文件、類蜡镶、方法的匹配規(guī)則和常用的命令參數(shù)雾袱,執(zhí)行時只需要命令行輸入D:\py_test>pytest就可以開始執(zhí)行自動化測試。也可以不用pytest.ini配置官还,命令行執(zhí)行D:\py_test>pytest -s test_login.py --html=report/report.html芹橡,-s參數(shù):輸出所有測試用例的print信息,安裝了pytest-html插件后望伦,在執(zhí)行命令中加入--html=測試報告保存路徑林说。
pytest.ini文件配置如下:

[pytest] 
# 打印print,生成保存報告 
addopts = -s --html=report/report.html 
# 匹配執(zhí)行文件 
python_files = test_*.py 
# 匹配執(zhí)行類 
python_classes = Test* 
# 匹配執(zhí)行方法 
python_functions = test_*

3.6 結果展示

可以在ide中執(zhí)行測試用例屯伞,也可以使用命令行執(zhí)行腿箩,執(zhí)行完測試用例后,會生成一個html格式的測試報告劣摇,在瀏覽器中打開就可以查看本次自動化測試的測試結果珠移。pytest不僅支持pytest-html插件,還可以使用allure生成更加美觀的測試報告末融。下面分別展示使用pytest-html和allure生成的html測試報告钧惧,pytest-html報告中記錄的內容比較詳盡,包括了用例運行日志勾习、通過\失敗\跳過用例條數(shù)浓瞪、用例運行時間等等。allure生成的報告可讀性比較強巧婶,可以很直觀的看到測試結果乾颁。

pytest-html生成的測試報告:

allure生成的測試報告:


4 總結

整個項目完成之后,對pytest測試框架有了更深的理解艺栈。同時英岭,pytest也可以使用Jenkins將自動化測試加入到持續(xù)集成中,設置定時任務構建或者條件觸發(fā)構建等眼滤,這樣可以有效的提高測試效率巴席,也節(jié)省了人力成本历涝。當然诅需,不僅僅只有這一種實現(xiàn)方式,目前的實現(xiàn)方式還是有很多不足的地方荧库,后面會繼續(xù)進行完善和改進堰塌。如果你有什么好的建議和方法,歡迎一起進行溝通和交流分衫。


我們是行者AI场刑,我們在“AI+游戲”中不斷前行。

如果你也對游戲感興趣蚪战,對AI充滿好奇牵现,那就快來加入我們吧~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末铐懊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞎疼,更是在濱河造成了極大的恐慌科乎,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贼急,死亡現(xiàn)場離奇詭異茅茂,居然都是意外死亡,警方通過查閱死者的電腦和手機太抓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門空闲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人走敌,你說我怎么就攤上這事碴倾。” “怎么了悔常?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵影斑,是天一觀的道長。 經常有香客問我机打,道長矫户,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任残邀,我火速辦了婚禮皆辽,結果婚禮上,老公的妹妹穿的比我還像新娘芥挣。我一直安慰自己驱闷,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布空免。 她就那樣靜靜地躺著空另,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蹋砚。 梳的紋絲不亂的頭發(fā)上扼菠,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音坝咐,去河邊找鬼循榆。 笑死,一個胖子當著我的面吹牛墨坚,可吹牛的內容都是我干的秧饮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盗尸!你這毒婦竟也來了柑船?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤泼各,失蹤者是張志新(化名)和其女友劉穎椎组,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體历恐,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡寸癌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弱贼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒸苇。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吮旅,靈堂內的尸體忽然破棺而出溪烤,到底是詐尸還是另有隱情,我是刑警寧澤庇勃,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布檬嘀,位于F島的核電站,受9級特大地震影響责嚷,放射性物質發(fā)生泄漏鸳兽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一罕拂、第九天 我趴在偏房一處隱蔽的房頂上張望揍异。 院中可真熱鬧,春花似錦爆班、人聲如沸衷掷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戚嗅。三九已至,卻和暖如春枢舶,著一層夾襖步出監(jiān)牢的瞬間懦胞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工祟辟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留医瘫,地道東北人侣肄。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓旧困,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吼具,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容