2013-09-26 72 views
17

我的测试套件,我一直在使用TestLoader的(从单元测试模块)loadTestsFromModule()方法,即装,没有修饰语法跳过单元测试的测试

suite = loader.loadTestsFromModule(module) 

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

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

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

单元测试文档suggests using decorators围绕测试方法或类。由于我从模块中加载这些测试,并根据测试本身不包含的标准判断跳过,所以我无法真正使用装饰器。有没有一种方法可以迭代每个单独的测试,还有一些如何将它标记为“跳过”测试,而无需直接访问类中的测试类或方法?

+0

您可能会考虑py.test,它具有[skipif](http://pytest.org/latest/skipping.html#marking-a-test-function-to-beed) –

回答

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) 

UPDATE

更新了代码修补setUp代替的试验方法。否则,将执行setUp/tearDown方法以跳过测试。

注意

unittest.TestCase.skipTest(测试跳跃)在Python 2.7推出时,3.1。所以这个方法只能在Python 2.7+,3.1+

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) 
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) 
+0

'test_method'不曾用过; 'test_method = getattr(test,test._testMethodName)'似乎没有必要。 – falsetru

+0

你是对的 - 删除。 – girasquid

+1

'raise unittest.SkipTest(reason)'正是我所期待的! – oliverpool

1

Google把我带到了这里。

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

from unittest.case import SkipTest 

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

并且该测试将被标记为跳过。