<自動化測試>之<使用unittest Python測試框架進行參數化測試>


最近在看視頻時,蟲師簡單提到了簡化自動化測試腳本用例中的代碼量,而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_3test_add_1_3_and_5

生成的測試用例的名稱@parameterized.expand可以使用testcase_func_namekeyword參數自定義。該值應該是這三個參數的函數:testcase_funcparam_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)

如果測試用例有一個docstring,則該測試用例的參數將追加到docstring的第一行。這個行為可以用doc_func參數控制:

from parameterized import parameterized @parameterized([ (1, 2, 3), (4, 5, 9), ]) def test_add(a, b, expected): """ Test addition. """ assert_equal(a + b, expected) def my_doc_func(func, num, param): return "%s: %s with %s" %(num, func.__name__, param) @parameterized([ (5, 4, 1), (9, 6, 3), ], doc_func=my_doc_func) def test_subtraction(a, b, expected): assert_equal(a - b, expected)
$ nosetests example.py Test addition. [with a=1, b=2, expected=3] ... ok Test addition. [with a=4, b=5, expected=9] ... ok 0: test_subtraction with param(*(5, 4, 1)) ... ok 1: test_subtraction with param(*(9, 6, 3)) ... ok ---------------------------------------------------------------------- Ran 4 tests in 0.001s OK

 

 

仔細學習可以查看在github上有詳盡的使用方法

 from @wolever wolever & thanks!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM