我在Python中使用unittest进行一些测试。我对FunctionTestCase感兴趣。从文档中,这是示例用法:
testcase = unittest.FunctionTestCase(testSomething,
setUp=makeSomethingDB,
tearDown=deleteSomethingDB)
testSomething定义为
def testSomething():
something = makeSomething()
assert something.name is not None
# ...
但是,我有兴趣将参数传递给testSomething(),如下所示。
def testSomething(input):
something = makeSomething(input)
assert something.name is not None
# ...
当我运行它时,如上所述构建它:
runner= unittest.TextTestRunner()
runner.run(testcase)
我得到了
ERROR: unittest.case.FunctionTestCase (test_meth4)
----------------------------------------------------------------------
TypeError: testSomething() missing 1 required positional argument: 'input'
----------------------------------------------------------------------
Ran 1 tests in 0.007s
有没有办法传递参数,还是需要使用像闭包/外部函数这样的东西?感谢
答案 0 :(得分:0)
看起来你可以将参数传递给正在测试的函数。在Python 2和3中,FunctionTestCase.runTest()
只包含一行:self._testFunc()
,没有提供传递参数的规定。您可以将FunctionTestCase
子类化并向其__init__()
添加参数,然后让runTest()
将它们传递给正在测试的函数:
import unittest
def my_func(arg1, arg2=None):
print('arg1 is', arg1)
print('arg2 is', arg2)
class MyFunctionTestCase(unittest.FunctionTestCase):
def __init__(self, testFunc, setUp=None, tearDown=None,
description=None, args=(), kwargs={}):
super(MyFunctionTestCase, self).__init__(testFunc, setUp=setUp,
tearDown=tearDown,
description=description)
self.args = args
self.kwargs = kwargs
def runTest(self):
self._testFunc(*self.args, **self.kwargs)
my_test = unittest.FunctionTestCase(my_func)
my_subclassed_test = MyFunctionTestCase(my_func, args=(42,), kwargs={'arg2': 24})
runner = unittest.TextTestRunner()
runner.run(my_test)
runner.run(my_subclassed_test)
我建议您在https://bugs.python.org申请此功能和/或更多文档。这似乎是一个很大的差距,实际上没有FunctionTestCase
的官方文档。
答案 1 :(得分:0)
如前所述,不可能使用 unittest.FunctionTestCase()
为您的测试函数提供参数。但是,您可以使用 functools.partial()
创建一个包装函数,该函数使用附加参数调用原始函数。
以您的原始示例为例,您可以执行以下操作:
wrapped_func = functools.partial(testSomething, input)
wrapped_func() # this is now equivalent to testSomething(input)
(请注意,input
也是 Python 中内置函数的名称,因此我建议您为变量使用另一个名称。)
基于另一个答案的完整工作示例(为了更容易比较)是这样的:
import functools
import unittest
def my_func(arg1, arg2=None):
print('arg1 is', arg1)
print('arg2 is', arg2)
my_wrapped_func = functools.partial(my_func, 42, arg2=24)
functools.update_wrapper(my_wrapped_func, my_func)
my_wrapped_test = unittest.FunctionTestCase(my_wrapped_func)
runner = unittest.TextTestRunner()
runner.run(my_wrapped_test)
带有 update_wrapper()
的行是必要的,以使包装的函数看起来更像原始函数,这是 unittest 框架在失败时打印函数名称所必需的。