20

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

suite = loader.loadTestsFromModule(module)

这给了我一个非常充足的测试列表,可以正常工作。我的问题是我正在使用的测试工具有时需要根据各种标准跳过某些测试。我想做的是这样的:

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

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

unittest 文档建议在测试方法或类周围使用装饰器。由于我从一个模块加载这些测试并根据测试本身不包含的标准决定跳过,所以我不能真正使用装饰器。有没有一种方法可以迭代每个单独的测试,以及如何将其标记为“跳过”测试,而无需直接访问测试类或类中的方法?

4

4 回答 4

11

使用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+

于 2013-09-26T15:50:53.777 回答
6

这有点小技巧,但是因为您只需要 raiseunittest.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)
于 2013-09-26T15:40:22.673 回答
6

谷歌把我带到了这里。

SkipTest我发现最简单的方法是在满足您的跳过条件时引发异常。

from unittest.case import SkipTest

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

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

于 2017-06-16T06:09:25.113 回答
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)
于 2013-09-26T15:22:08.457 回答