­

單元測試工具(連載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