单元测试工具(连载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