2013-09-26 110 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 

並且該測試將被標記爲跳過。