跳过没有装饰器语法的unittest测试

时间:2013-09-26 15:08:59

标签: python unit-testing

我使用TestLoader(来自unittest模块)loadTestsFromModule()方法加载了一套测试,即

suite = loader.loadTestsFromModule(module)

这为我提供了一个完美的测试列表。我的问题是,我正在使用的测试工具有时需要根据各种标准跳过某些测试。我想做的是这样的事情:

for test in suite:
    mark the test as 'to-skip' if it meets certain criteria

请注意,我不能只从测试列表中删除测试,因为我希望unittest测试运行器实际跳过测试,将它们添加到跳过的计数,以及所有爵士乐。

测试方法或类的单元测试文档suggests using decorators。因为我从模块加载这些测试并根据测试本身未包含的标准确定跳过,所以我不能真正使用装饰器。有没有办法可以迭代每个单独的测试,有些人如何将其标记为“跳过”测试,而无需直接访问类中的测试类或方法?

4 个答案:

答案 0 :(得分:9)

使用unittest.TestCase.skipTest

import unittest

class TestFoo(unittest.TestCase):
    def setUp(self): print('setup')
    def tearDown(self): print('teardown')
    def test_spam(self): pass
    def test_egg(self): pass
    def test_ham(self): pass

if __name__ == '__main__':
    import sys
    loader = unittest.loader.defaultTestLoader
    runner = unittest.TextTestRunner(verbosity=2)
    suite = loader.loadTestsFromModule(sys.modules['__main__'])
    for ts in suite:
        for t in ts:
            if t.id().endswith('am'): # To skip `test_spam` and `test_ham`
                setattr(t, 'setUp', lambda: t.skipTest('criteria'))
    runner.run(suite)

打印

test_egg (__main__.TestFoo) ... setup
teardown
ok
test_ham (__main__.TestFoo) ... skipped 'criteria'
test_spam (__main__.TestFoo) ... skipped 'criteria'

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK (skipped=2)


----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK (skipped=2)

<强>更新

更新了代码以修补setUp而不是测试方法。否则,将执行setUp / tearDown方法以便跳过测试。

注意

unittest.TestCase.skipTest(测试跳过)是在Python 2.7,3.1 中引入的。因此,此方法仅适用于 Python 2.7 +,3.1 +

答案 1 :(得分:6)

这有点像黑客攻击,但是因为你只需要提升unittest.SkipTest,你就可以遍历你的套件并修改每个测试来为你提升它而不是运行实际的测试代码:

import unittest
from unittest import SkipTest

class MyTestCase(unittest.TestCase):
    def test_this_should_skip(self):
        pass

    def test_this_should_get_skipped_too(self):
        pass

def _skip_test(reason):
    raise SkipTest(reason)

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(MyTestCase)
    for test in suite:
        skipped_test_method = lambda: _skip_test("reason")
        setattr(test, test._testMethodName, skipped_test_method)
    unittest.TextTestRunner(verbosity=2).run(suite)

当我运行它时,这是我得到的输出:

test_this_should_get_skipped_too (__main__.MyTestCase) ... skipped 'reason'
test_this_should_skip (__main__.MyTestCase) ... skipped 'reason'

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK (skipped=2)

答案 2 :(得分:4)

谷歌把我带到了这里。

我发现最简单的方法是在满足跳过条件时提出SkipTest例外。

from unittest.case import SkipTest

def test_this_foo(self):
    if <skip conditsion>:
        raise SkipTest

该测试将被标记为已跳过。

答案 3 :(得分:1)

一些观察结果:

  • 测试是具有__call__(result)方法
  • 的可调用对象
  • TestCase提供更高级别的界面,允许测试方法抛出SkipTest异常以跳过自己
  • skip装饰器正是这样做的
  • 使用TestResult.addSkip(test, reason)方法记录跳过的测试。

因此,您只需要使用调用addSkip的自定义测试替换要跳过的测试:

class Skipper(object):
    def __init__(self, test, reason):
        self.test = test
        self.reason = reason

    def __call__(self, result):
        result.addSkip(self.test, self.reason)