單元測試工具(連載13)
- 2019 年 12 月 12 日
- 筆記
4.6 參數化
Pytest可以通過fixtures、Mark_Usefixtures和外部數據對測試用例進行參數化。
1. 通過fixtures參數化
案例15:通過fixtures參數化。
#利用fixtures的params
import pytest
from Calculator import calculator
from Util import util
@pytest.fixture(params=[{'first':20,"second":30,"result":50},{'first':20,"second":20,"result":40}])
defaccount_provider(request): #request是固定的。
return request.param #request.parm也是固定的。
def test_Calculato(account_provider):
j=calculator(account_provider["first"],account_provider["second"])
util.AssertEqual(j.myadd(),account_provider["result"])
if __name__ == '__main__':
pytest.main(["-sv","Test_Parms_By_Pytest_Fixture.py"])
運行結果如下。
…
collected 2 items [0m
[32m[1m========================== 2 passed in 0.32 seconds===========================[0m
>>>
由於這裡有兩個參數,所以測試用例認為這裡有兩個測試用例。
通過Mark_Usefixtures參數化
案例16:通過Mark_Usefixtures參數化。
#利用Mark_Usefixtures的params
import pytest
from Calculator importcalculator
from Util import util
@pytest.fixture(params=[{'first':20,"second":30,"result":50},{'first':20,"second":20,"result":40}])
defaccount_provider(request): #request是固定的。
return request.param #request.parm也是固定的。
@pytest.mark.usefixtures("account_provider")
deftest_Calculato(account_provider):
j=calculator(account_provider["first"],account_provider["second"])
util.AssertEqual(j.myadd(),account_provider["result"])
if __name__ =='__main__':
pytest.main(["-sv","Test_Parms_By_Mark_Usefixtures.py"])
注意:使用fixture標記函數後,函數將默認接入一個request參數,它將包含使用該fixture函數的資訊,這使我們可以更加靈活的根據不同的函數來決定創建不同的對象以及釋放函數。舉例來說userfixtures可以用作setup()和teardown()。
3. 通過外部數據參數化
案例17:通過外部數據參數化。
Util.py讀取本目錄下名為data.xlsx的Excel文件,文件格式如圖36所示。
import xlrd
from xlutils.copy import copy
…
#讀取Excel文件
def read_from_excel():
fname = './data.xlsx』
filename = xlrd.open_workbook(fname)
sheets = filename.nsheets
sheet1 = filename.sheets()[0]
nrows1 = sheet1.nrows
row_list = []
fori in range(0,nrows1):
row_datas = sheet1.row_values(i)
row_list.append(row_datas)
return row_list
測試程式。
import pytest
from Calculator import calculator
from Util import util
#直接寫函數讀取外部文件生成數據值,注意values返回值是個list
values = util.read_from_excel()
@pytest.mark.parametrize('v',values)
def test_login(v):
print(values)
print(v)
j=calculator(v[0],v[1])
util.AssertEqual(j.myadd(),v[2])
if __name__ == '__main__':
pytest.main(["-sv","Test_Parms_By_Pytest_Mark_Parametrize.py"])

圖36 data.xlsx文件格式
運行結果為。
…
Test_Parms_By_Pytest_Mark_Parametrize.py::test_login[v0] [[100.0, 200.0, 300.0],[1.0, 5.0, 6.0]]
[100.0, 200.0, 300.0]
[32mPASSED[0m
Test_Parms_By_Pytest_Mark_Parametrize.py::test_login[v1] [[100.0, 200.0, 300.0],[1.0, 5.0, 6.0]]
[1.0, 5.0, 6.0]
[32mPASSED[0m
[32m[1m========================== 2 passed in 0.28seconds ===========================[0m
測試框架把Excel第一列賦值給v1、第二列賦值給v2,…。
4.7 簡易計算器測試用例用pytest最終實現方式
利用以上的各種方法,優化了最後簡易計算器測試用例的最優化,程式碼如下。
案例18:用pytest實現簡易計算器的測試的最終程式碼。
#coding=utf-8
import pytest
from Util import util
from Calculator import calculator
import allure
@pytest.fixture(params=[{'first':4,"second":2,"result":2},{'first':2,"second":4,"result":-2},{'first':4,"second":4,"result":0}])
def subs_provider(request):
returnrequest.param
@pytest.fixture(params=[{'first':4,"second":2,"result":8},{'first':4,"second":-2,"result":-8},{'first':-4,"second":2,"result":-8},{'first':-4,"second":-2,"result":8}])
def multiply_provider(request):
returnrequest.param
class TestCalculator:
defsetup_class(self):
print("測試開始")
@allure.feature('test_module_Calculator')
@allure.story('test_story_01')
@allure.severity('blocker')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
deftest_base(self):
"""
用例描述:測試加、減、乘、除基本功能
"""
j=calculator(4,2)
util.AssertEqual(j.myadd(),6)
util.AssertEqual(j.mysubs(),2)
util.AssertEqual(j.mymultiply(),8)
util.AssertEqual(j.mydivide(),2)
@allure.feature('test_module_Calculator')
@allure.story('test_story_01')
@allure.severity('Normal')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
deftest_max_number(self):
"""
用例描述:測試很大的數字
"""
j=calculator(9223372036854775808,9223372036854775808)
util.AssertEqual(j.mymultiply(),85070591730234615865843651857942052864)
@allure.feature('test_module_Calculator')
@allure.story('test_story_01')
@allure.severity('Critical')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
deftest_subs(self,subs_provider):
"""
用例描述:測試商為正數、負數和0
"""
j=calculator(subs_provider["first"],subs_provider["second"])
util.AssertEqual(j.mysubs(),subs_provider["result"])
@allure.feature('test_module_Calculator')
@allure.story('test_story_01')
@allure.severity('Critical')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
def test_multiply(self,multiply_provider):
"""
用例描述:測試正數乘正數、正數乘負數、負數乘正數和負數乘負數
"""
j=calculator(multiply_provider["first"],multiply_provider["second"])
util.AssertEqual(j.mymultiply(),multiply_provider["result"])
@allure.feature('test_module_Calculator')
@allure.story('test_story_01')
@allure.severity('Critical')
@allure.issue("http://www.jila.com")
@allure.testcase("http://www.testlink.com")
deftest_divide(self):
"""
用例描述:除數為0
"""
j=calculator(4,0)
util.AssertEqual(j.mydivide(),0)
defteardown_class(self):
print("測試結束")
if __name__ == '__main__':
pytest.main(['-sv', '-q', '–alluredir', './report/xml'])
最後的測試報告如圖37。

圖37 簡易計算器基於allure生成pytest 測試報告
星雲測試
http://www.teststars.cc
奇林軟體
http://www.kylinpet.com
聯合通測
http://www.quicktesting.net