Python 测试如何 运行 参数化测试用例并将参数传递给 setupClass
Python Testing how to run parameterised Testcases and pass a parameter to setupClass
我有一个 python 单元测试。在 setupClass 方法中,我执行了一些耗时的任务...测试本身 运行 非常快。现在我想 运行 具有多组参数的相同测试用例。我怎样才能做到这一点?
我已经尝试过 nose_parameterized 等不同的方法,但我不能使用 @parameterized.expand()
import unittest
from nose_parameterized import parameterized
parameters = [('test1', 2 ),('test2', 3)]
class TestParameterizedTestcase(unittest.TestCase):
@classmethod
def setUpClass(cls, param=1):
"""
Do some expensive stuff
"""
cls.param = param
print 'Param in setup class %s'
def test_is_one(self):
"""
A fast test
"""
self.assertEqual(1,self.param)
def test_is_two(self):
"""
Another fast test
"""
self.assertEqual(2, self.param)
def test_is_three(self):
"""
Another fast test
"""
self.assertEqual(3, self.param)
遗憾的是,没有任何方法可以使用 unittest
、nose
或 parameterized
创建参数化测试 classes。
py.test
有一个示例显示如何构建自己的参数化测试 class,此处:https://pytest.org/latest/example/parametrize.html#a-quick-port-of-testscenarios
您可以像这样构建自己的参数化 class 生成器:
class MyTestClassBase(object):
# Inherit from `object` so unittest doesn't think these are tests which
# should be run
@classmethod
def setUpClass(cls):
print "doing expensive setup with", cls.param
def test_one(self):
self.assertEqual(self.param, 1)
params = [('test1', 1), ('test2', 2)]
for name, param in params:
cls_name = "TestMyTestClass_%s" %(name, )
globals()[cls_name] = type(cls_name, (MyTestClassBase, unittest.TestCase), {
"param": param,
})
这将为每个参数生成一个新测试 class。
为了完整性,这里有一种使用单元测试的方法,但我更喜欢戴维斯的回答。
导入单元测试
从 nose_parameterized 导入参数化
class TestParameterizedTestcase(unittest.TestCase):
param =3
@classmethod
def setUpClass(cls):
"""
Do some expensive stuff
"""
print 'Param in setup class %s' % cls.param
def test_is_one(self):
"""
Some fast test
"""
self.assertEqual(1,self.param)
def test_is_two(self):
"""
Anoter Fast test
"""
self.assertEqual(2, self.param)
import unittest
from unittest import TestLoader
if __name__ == '__main__':
for param in range(5):
suite = unittest.TestSuite()
loader = TestLoader()
test = None
test = TestParameterizedTestcase
test.param =param
tests = loader.loadTestsFromTestCase(test)
suite.addTest(tests)
unittest.TextTestRunner().run(suite)
如果您有多个参数并且只能调用具有这些值的方法,则可以使用以下方法:
import unittest
from parameterized import parameterized
def custom_name_func(testcase_func, param_num, param):
"""
The names of the test cases generated by @parameterized.expand
:param testcase_func: will be the function to be tested
:param param_num: will be the index of the test case parameters in the list of parameters
:param param: (an instance of param) will be the parameters which will be used.
:return: test case name
"""
return "%s_%s" % (
testcase_func.__name__,
parameterized.to_safe_name("_".join([str(param.args[0]), param_num])),
)
class SomeTestCase(unittest.TestCase):
@parameterized.expand([
('ex1', 2, 3, 5),
('ex2', 2, 5, 7),
('ex3', 3, 8, 11)
], name_func=custom_name_func)
def test_add(self, name, a, b, expected):
self.assertEqual(a + b, expected)
运行 测试将 return:
python -m unittest /tests/test_one.py -v
test_add_ex1_0 (tests.test_one.SomeTestCase) ... ok
test_add_ex2_1 (tests.test_one.SomeTestCase) ... ok
test_add_ex3_2 (tests.test_one.SomeTestCase) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.000s
我有一个 python 单元测试。在 setupClass 方法中,我执行了一些耗时的任务...测试本身 运行 非常快。现在我想 运行 具有多组参数的相同测试用例。我怎样才能做到这一点?
我已经尝试过 nose_parameterized 等不同的方法,但我不能使用 @parameterized.expand()
import unittest
from nose_parameterized import parameterized
parameters = [('test1', 2 ),('test2', 3)]
class TestParameterizedTestcase(unittest.TestCase):
@classmethod
def setUpClass(cls, param=1):
"""
Do some expensive stuff
"""
cls.param = param
print 'Param in setup class %s'
def test_is_one(self):
"""
A fast test
"""
self.assertEqual(1,self.param)
def test_is_two(self):
"""
Another fast test
"""
self.assertEqual(2, self.param)
def test_is_three(self):
"""
Another fast test
"""
self.assertEqual(3, self.param)
遗憾的是,没有任何方法可以使用 unittest
、nose
或 parameterized
创建参数化测试 classes。
py.test
有一个示例显示如何构建自己的参数化测试 class,此处:https://pytest.org/latest/example/parametrize.html#a-quick-port-of-testscenarios
您可以像这样构建自己的参数化 class 生成器:
class MyTestClassBase(object):
# Inherit from `object` so unittest doesn't think these are tests which
# should be run
@classmethod
def setUpClass(cls):
print "doing expensive setup with", cls.param
def test_one(self):
self.assertEqual(self.param, 1)
params = [('test1', 1), ('test2', 2)]
for name, param in params:
cls_name = "TestMyTestClass_%s" %(name, )
globals()[cls_name] = type(cls_name, (MyTestClassBase, unittest.TestCase), {
"param": param,
})
这将为每个参数生成一个新测试 class。
为了完整性,这里有一种使用单元测试的方法,但我更喜欢戴维斯的回答。
导入单元测试 从 nose_parameterized 导入参数化
class TestParameterizedTestcase(unittest.TestCase):
param =3
@classmethod
def setUpClass(cls):
"""
Do some expensive stuff
"""
print 'Param in setup class %s' % cls.param
def test_is_one(self):
"""
Some fast test
"""
self.assertEqual(1,self.param)
def test_is_two(self):
"""
Anoter Fast test
"""
self.assertEqual(2, self.param)
import unittest
from unittest import TestLoader
if __name__ == '__main__':
for param in range(5):
suite = unittest.TestSuite()
loader = TestLoader()
test = None
test = TestParameterizedTestcase
test.param =param
tests = loader.loadTestsFromTestCase(test)
suite.addTest(tests)
unittest.TextTestRunner().run(suite)
如果您有多个参数并且只能调用具有这些值的方法,则可以使用以下方法:
import unittest
from parameterized import parameterized
def custom_name_func(testcase_func, param_num, param):
"""
The names of the test cases generated by @parameterized.expand
:param testcase_func: will be the function to be tested
:param param_num: will be the index of the test case parameters in the list of parameters
:param param: (an instance of param) will be the parameters which will be used.
:return: test case name
"""
return "%s_%s" % (
testcase_func.__name__,
parameterized.to_safe_name("_".join([str(param.args[0]), param_num])),
)
class SomeTestCase(unittest.TestCase):
@parameterized.expand([
('ex1', 2, 3, 5),
('ex2', 2, 5, 7),
('ex3', 3, 8, 11)
], name_func=custom_name_func)
def test_add(self, name, a, b, expected):
self.assertEqual(a + b, expected)
运行 测试将 return:
python -m unittest /tests/test_one.py -v
test_add_ex1_0 (tests.test_one.SomeTestCase) ... ok
test_add_ex2_1 (tests.test_one.SomeTestCase) ... ok
test_add_ex3_2 (tests.test_one.SomeTestCase) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.000s