nose-parameterized是一个针对Python单元测试框架实现参数化的扩展。同时支持不同的单元测试框架。
GitHub地址:https://github.com/wolever/nose-parameterized
import unittest
from nose_parameterized import parameterized
class TestAdd(unittest.TestCase):
#前置用例
arr = [
{"用例ID":"a","前置ID":"b","等级":"c","http方法":"d","接口url":"e","接口参数":"f","前置用例返回结果":"g","预期结果":"h","描述":"i"},
{"用例ID":"1","参数1":"1","参数2":"6"},
]
#用例
@parameterized.expand([
# ('用例ID', '前置ID', '等级', 'http方法', '接口url', '接口参数', '前置用例返回结果', '预期结果', '描述'),
(1,'',1, 1, 2),
(2,'',2, 2, 5),
(3,1,3, 3, 6),
])
def test_add(self, name, a, b, c,d):
if(a !=''):
tmp = TestAdd.arr[a]
value = int(tmp["参数1"]) + int(tmp["参数2"])
# print(b + value)
self.assertEqual(value + c, d)
else:
# print(b + c)
self.assertEqual(b + c, d)
if __name__ == '__main__':
unittest.main(verbosity=2)
执行结果:
test_add_0_01 (__main__.TestAdd) ... ok
test_add_1_02 (__main__.TestAdd) ... FAIL
test_add_2_03 (__main__.TestAdd) ... ok
当相传入参和断言结果的用例越多,这种写法用起来越爽!
最近在看视频时,虫师简单提到了简化自动化测试脚本用例中的代码量,而python中本身的参数化方法用来测试很糟糕,他在实际操作中使用了parameterized参数化...
有兴趣就查了下使用的方法,来分享给大家,使用Python测试框架进行参数化测试 下载安装https://github.com/wolever/parameterized或PIP install: $ pip install parameterized
parameterized
了修正对于一切nose参数化测试,py.test参数化测试,单元测试参数化测试。
# test_math.py from nose.tools import assert_equal from parameterized import parameterized import unittest import math @parameterized([ (2, 2, 4), (2, 3, 8), (1, 9, 1), (0, 9, 0), ]) def test_pow(base, exponent, expected): assert_equal(math.pow(base, exponent), expected) class TestMathUnitTest(unittest.TestCase): @parameterized.expand([ ("negative", -1.5, -2.0), ("integer", 1, 1.0), ("large fraction", 1.6, 1), ]) def test_floor(self, name, input, expected): assert_equal(math.floor(input), expected)
在 nose (and nose2)下运行: $ nosetests -v test_math.py test_math.test_pow(2, 2, 4) ... ok test_math.test_pow(2, 3, 8) ... ok test_math.test_pow(1, 9, 1) ... ok test_math.test_pow(0, 9, 0) ... ok test_floor_0_negative (test_math.TestMathUnitTest) ... ok test_floor_1_integer (test_math.TestMathUnitTest) ... ok test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok ---------------------------------------------------------------------- Ran 7 tests in 0.002s OK As the package name suggests, nose is best supported and will be used for all further examples. With py.test (version 2.0 and above): $ py.test -v test_math.py ============================== test session starts ============================== platform darwin -- Python 2.7.2 -- py-1.4.30 -- pytest-2.7.1 collected 7 items test_math.py::test_pow::[0] PASSED test_math.py::test_pow::[1] PASSED test_math.py::test_pow::[2] PASSED test_math.py::test_pow::[3] PASSED test_math.py::TestMathUnitTest::test_floor_0_negative test_math.py::TestMathUnitTest::test_floor_1_integer test_math.py::TestMathUnitTest::test_floor_2_large_fraction =========================== 7 passed in 0.10 seconds ============================ With unittest (and unittest2): $ python -m unittest -v test_math test_floor_0_negative (test_math.TestMathUnitTest) ... ok test_floor_1_integer (test_math.TestMathUnitTest) ... ok test_floor_2_large_fraction (test_math.TestMathUnitTest) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK (note: because unittest does not support test decorators, only tests created with @parameterized.expand will be executed)
在@parameterized与@parameterized.expand装饰接受列表或可迭代的元组或param(...),或调用它返回一个列表或可迭代, 下面是比较全的使用方法示例:
from parameterized import parameterized, param # A list of tuples @parameterized([ (2, 3, 5), (3, 5, 8), ]) def test_add(a, b, expected): assert_equal(a + b, expected) # A list of params @parameterized([ param("10", 10), param("10", 16, base=16), ]) def test_int(str_val, expected, base=10): assert_equal(int(str_val, base=base), expected) # An iterable of params @parameterized( param.explicit(*json.loads(line)) for line in open("testcases.jsons") ) def test_from_json_file(...): ... # A callable which returns a list of tuples def load_test_cases(): return [ ("test1", ), ("test2", ), ] @parameterized(load_test_cases) def test_from_function(name): ...
请注意,在使用迭代器或生成器时,在开始测试运行之前,所有项目都将被加载到内存中(我们明确地做到这一点,以确保生成器在多进程或多线程测试环境中精确地耗尽一次) 。
@parameterized
装饰可用于测试类的方法,和独立的功能:
from parameterized import parameterized class AddTest(object): @parameterized([ (2, 3, 5), ]) def test_add(self, a, b, expected): assert_equal(a + b, expected) @parameterized([ (2, 3, 5), ]) def test_add(a, b, expected): assert_equal(a + b, expected)
并且@parameterized.expand
可以用于在不能使用测试生成器的情况下生成测试方法(例如,当测试类是子类时unittest.TestCase
):
import unittest from parameterized import parameterized class AddTestCase(unittest.TestCase): @parameterized.expand([ ("2 and 3", 2, 3, 5), ("3 and 5", 2, 3, 5), ]) def test_add(self, _, a, b, expected): assert_equal(a + b, expected)
会创建测试用例:
$ nosetests example.py test_add_0_2_and_3 (example.AddTestCase) ... ok test_add_1_3_and_5 (example.AddTestCase) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
请注意,@parameterized.expand
通过在测试类上创建新方法。如果第一个参数是一个字符串,该字符串将被添加到方法名称的末尾。例如,上面的测试用例会生成方法 test_add_0_2_and_3
和test_add_1_3_and_5
。
生成的测试用例的名称@parameterized.expand
可以使用testcase_func_name
keyword参数自定义。该值应该是这三个参数的函数:testcase_func
,param_num
,和params
,应该返回测试用例的名字。 testcase_func
将被测试的功能,param_num
将参数列表中的测试用例参数的索引,和param
(一个实例param
)将被使用的参数。
import unittest from parameterized import parameterized def custom_name_func(testcase_func, param_num, param): return "%s_%s" %( testcase_func.__name__, parameterized.to_safe_name("_".join(str(x) for x in param.args)), ) class AddTestCase(unittest.TestCase): @parameterized.expand([ (2, 3, 5), (2, 3, 5), ], testcase_func_name=custom_name_func) def test_add(self, a, b, expected): assert_equal(a + b, expected)
创建测试用例:
$ nosetests example.py test_add_1_2_3 (example.AddTestCase) ... ok test_add_2_3_5 (example.AddTestCase) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
该param(...)
助手类存储一个特定的测试情况的参数。它可以用于将关键字参数传递给测试用例:
from parameterized import parameterized, param @parameterized([ param("10", 10), param("10", 16, base=16), ]) def test_int(str_val, expected, base=10): assert_equal(int(str_val, base=base), expected)
测试用例描述,这个行为可以用doc_func
参数控制:
import unittest from parameterized import parameterized def custom_name_func(testcase_func, param_num, param): print('param_num:'+str(param_num)) print('param:'+str(param)) # print(param.args[2]) return "%s: %s with %s" % (param_num, testcase_func.__name__, param) class AddTestCase(unittest.TestCase): '''aaaaaaaaaa''' @parameterized.expand([ (1, 2, 3), (5, 6, 7), ], doc_func=custom_name_func) def test_add(self, a, b, expected): print('aaa') self.assertEqual(a + b, expected)
仔细学习可以查看在github上有详尽的使用方法
from wolever & thanks!!!