pytest支援資料驅動
基礎舉例:
import pytest
@pytest.mark.parametrize("a,b,c",[[1,2,3],[3,4,7]])
def test_add(a,b,c):
assert a+b==c
執行時,将分别使用上面兩組資料,執行兩個test。
實際中我們經常使用excel檔案來提供資料。是以實作excel資料驅動。
實作思路:
将讀取出的excel檔案中的标題行中各個單元格使用逗号連接配接成一個字元串,資料以雙重清單的方式傳回,作為@pytest.mark.parametrize()的參數即可。
我實作一個函數,get_data_from_sheet(excel_file_path,sheet_name)。以字元串形式傳回标題欄,同時以雙重清單的方式傳回data。@pytest.mark.parametrize (*get_data_from_sheet(excel_file_path,sheet_name))使用資料。具體代碼和使用舉例如下:
#python3.6
#coding=utf-8
#author=劉一凡
'''
支援pytest excel資料驅動。
'''
import pytest
import xlrd
#把excel sheet解析為雙層清單,每一個行是一個外層元素,每個單元格是一個内層元素。
def sheet_to_list(excel_file_path,sheet_name):
lst = []
with xlrd.open_workbook(excel_file_path) as f:
table = f.sheet_by_name(sheet_name)
#nrows是sheet的行數
for row in range(0,table.nrows):
lst.append([])
#ncols是sheet的列數
for col in range(0,table.ncols):
#ctype為1是字元串,ctype為2是數值。
cell_type = table.cell(row,col).ctype
cell_value = table.cell_value(row,col)
#去掉字元串首尾空格。excel會自動去掉整數和浮點數前後的空格。
if cell_type == 1:
lst[row].append(cell_value.strip())
#xlrd讀取cell時1變成1.0。如果是數值,并且原本是整數,則傳回整數。
elif cell_type == 2 and cell_value == round(cell_value):
lst[row].append(int(cell_value))
#浮點數則不用額外處理
else:
lst[row].append(cell_value)
return lst
#從excel sheet中擷取@pytest.mark.parametrize()所需要的參數名和資料
def get_data_from_sheet(excel_file_path,sheet_name):
lst = sheet_to_list(excel_file_path,sheet_name)
#參數名格式化,格式為"a,b,c"
param_name = ','.join(lst[0])
#去掉參數名行,剩下的就是資料
data = lst[1:]
return param_name, data
#使用舉例:
@pytest.mark.parametrize(*get_data_from_sheet("test_data.xlsx","add_test"))
def test_add(a,b,c):
assert a+b==c
'''
運作結果如下:
>pytest pytest_ddt_excel.py -v
============================= test session starts =============================
collected 4 items
pytest_ddt_excel.py::test_add[1-2-3] PASSED [ 25%]
pytest_ddt_excel.py::test_add[abc-def-abcdef] PASSED [ 50%]
pytest_ddt_excel.py::test_add[abc-123-abc123] PASSED [ 75%]
pytest_ddt_excel.py::test_add[1.8-2.6-4.4] PASSED [100%]
========================== 4 passed in 0.11 seconds ===========================
'''