运行生成的鼻子测试
假设我定义了一个叫做 testFile.py
的 Python 模块,内容如下。
def test_evens():
for i in range(0, 5):
yield check_even, i, i*3
def check_even(n, nn):
assert n % 2 == 0 or nn % 2 == 0
当我让 nose 在只收集测试的模式下识别测试时,我得到了
testFile.test_evens(0, 0) ... ok
testFile.test_evens(1, 3) ... ok
testFile.test_evens(2, 6) ... ok
testFile.test_evens(3, 9) ... ok
testFile.test_evens(4, 12) ... ok
我可以使用以下命令运行所有测试:
nosetests -v testFile:test_evens
但是,如果我只想运行 testFile.test_evens(2, 6) 这个测试(也就是说,不想运行所有的测试)呢?
有没有办法从命令行做到这一点?
1 个回答
7
根据我所知道的,Nose 默认情况下无法做到这一点。这里有一些选项:
1. 从命令行模拟
这可能不是你想要的,但我还是得提一下。你也可以创建一个包装脚本来简化这个过程:
python -c 'import testFile; testFile.check_even(2, 6)'
2. 创建一个自定义的 Nose 测试加载器
这个方法稍微复杂一点,但你可以创建一个自定义的测试加载器,它会把命令行参数当作要加载的生成器,提取生成器中的测试和参数,然后返回一个包含匹配参数的测试套件。
下面是一些示例代码,应该能给你一些基础来进行扩展(runner.py):
import ast
import nose
class CustomLoader(nose.loader.TestLoader):
def loadTestsFromName(self, name, module=None):
# parse the command line arg
parts = name.split('(', 1)
mod_name, func_name = parts[0].split('.')
args = ast.literal_eval('(' + parts[1])
# resolve the module and function - you'll probably want to
# replace this with nose's internal discovery methods.
mod = __import__(mod_name)
func = getattr(mod, func_name)
# call the generator and gather all matching tests
tests = []
if nose.util.isgenerator(func):
for test in func():
_func, _args = self.parseGeneratedTest(test)
if _args == args:
tests.append(nose.case.FunctionTestCase(_func, arg=_args))
return self.suiteClass(tests)
nose.main(testLoader=CustomLoader)
执行它:
% python runner.py 'testFile.test_evens(2, 6)' -v
testFile.check_even(2, 6) ... ok
% python runner.py 'testFile.test_evens(2, 6)' 'testFile.test_evens(4, 12)' -v
testFile.check_even(2, 6) ... ok
testFile.check_even(4, 12) ... ok
% python runner.py 'testFile.test_evens(1, 3)' -v
testFile.check_even(1, 3) ... FAIL