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 测试报告
星云测试
奇林软件
联合通测
顾翔凡言:
k=(p+m)t
其中:
k为常数。
p:团队人员质量水平,为单位小时内产生的有效质量,单位为/h;
m:团队方法质量水平,为单位小时内产生的有效质量,单位为/h;
t:为单位质量产品的交付时间,单位为h。
在团队方法质量水平不变,团队人员质量水平提高的情况下,交付时间变短;
在团队人员质量水平不变,团队方法质量水平提高的情况下,交付时间变短;
团队人员质量水平与方法质量水平乘积决定了软件的质量水平,如果这个值变小,则t变大;反之t变小。
例如,当k=4时:
当人员质量水平为1/小时、方法水平为1/小时时,交付时间为2小时。
当人员质量水平为2/小时、方法水平为1/小时时,交付时间为4/3小时。
当人员质量水平为1/小时、方法水平为2/小时时,交付时间为4/3小时。
当人员质量水平为0.5/小时、方法水平为0.5/小时时,交付时间为4小时。