2012-06-09 62 views
0

我的問題很簡單:我正在使用pymox進行一堆單元測試。當我添加一個失敗的新測試時,大多數時候很多其他測試失敗。我怎樣才能防止這種情況發生?爲什麼使用mox失敗的測試失敗了其他測試?

例如,我有一個簡單的腳本,我有兩個單元測試:

def test_main_returnsUnknown_ifCalculator_returnsMinus1(self): 
    m=mox.Mox() 
    m.StubOutWithMock(check_es_insert,"getArgs") 
    check_es_insert.getArgs(\ 
     'Nagios plugin for checking the total number of documents stored in Elasticsearch')\ 
     .AndReturn({ 'critical' : 7, 'warning' : 5, 'address' : 'myhost:1234', 'file' : '/tmp/bla'}) 
    ################ 
    #some other mocking here, not relevant, I think 
    ################ 
    m.ReplayAll() 
    #now let's test 
    check_es_docs.main() 
    #verify and cleanup 
    m.UnsetStubs() 
    m.VerifyAll() 
    m.ResetAll() 
def test_main_doesWhatPrintAndExitSays_inNormalConditions(self): 
    m=mox.Mox() 
    m.StubOutWithMock(check_es_insert,"getArgs") 
    check_es_insert.getArgs(\ 
     'Nagios plugin for checking the total number of documents stored in Elasticsearch')\ 
     .AndReturn({ 'critical' : 7, 'warning' : 5, 'address' : 'myhost:1234', 'file' : '/tmp/bla'}) 
    ################ 
    #some other mocking here, not relevant, I think 
    ################ 
    m.ReplayAll() 
    #now let's test 
    check_es_docs.main() 
    #verify and clean up 
    m.UnsetStubs() 
    m.VerifyAll() 
    m.ResetAll() 

通常情況下,這兩個測試通過,但如果我在一個錯字偷偷上我的第二個測試中,我得到這個輸出時運行測試:

$ ./check_es_docs.test.py 
FE 
====================================================================== 
ERROR: test_main_returnsUnknown_ifCalculator_returnsMinus1 (__main__.Main) 
If it can't get the current value from ES, print an error message and exit 3 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "./check_es_docs.test.py", line 13, in test_main_returnsUnknown_ifCalculator_returnsMinus1 
    m.StubOutWithMock(check_es_insert,"getArgs") 
    File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 312, in StubOutWithMock 
    raise TypeError('Cannot mock a MockAnything! Did you remember to ' 
TypeError: Cannot mock a MockAnything! Did you remember to call UnsetStubs in your previous test? 

====================================================================== 
FAIL: test_main_doesWhatPrintAndExitSays_inNormalConditions (__main__.Main) 
If getCurrent returns a positive value, main() should print the text and exit with the code Calculator.printandexit() says 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "./check_es_docs.test.py", line 69, in test_main_doesWhatPrintAndExitSays_inNormalConditions 
    check_es_docs.main() 
    File "/home/radu/check_es_docs.py", line 25, in main 
    check_es_insert.printer("Total number of documents in Elasticsearch is %d | 'es_docs'=%d;%d;%d;;" % (result,result,cmdline['warning'],cmdline['critical'])) 
    File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 765, in __call__ 
    return mock_method(*params, **named_params) 
    File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 1002, in __call__ 
    expected_method = self._VerifyMethodCall() 
    File "/usr/local/lib/python2.7/dist-packages/mox-0.5.3-py2.7.egg/mox.py", line 1060, in _VerifyMethodCall 
    raise UnexpectedMethodCallError(self, expected) 
UnexpectedMethodCallError: Unexpected method call. unexpected:- expected:+ 
- printer.__call__("Total number of documents in Elasticsearch is 3 | 'es_docs'=3;5;7;;") -> None 
?       - 

+ printer.__call__("Total nuber of documents in Elasticsearch is 3 | 'es_docs'=3;5;7;;") -> None 

---------------------------------------------------------------------- 
Ran 2 tests in 0.002s 

FAILED (failures=1, errors=1) 

第一次測試應該沒有錯誤通過,因爲它沒有改變一點。 check_es_insert.getArgs()不應該是MockAnything實例,我也不會忘記調用UnsetStubs。我搜查了很多,我沒有找到其他人有同樣的問題。所以我想我失去了一些東西很明顯...

附加信息:

  • check_es_docs是我測試
  • check_es_insert腳本另一個腳本從我進口了大量的東西
  • 我試圖把UnsetStubs()VerifyAll後()與
  • 我試着從安裝方法初始化mox.Mox()對象相同的結果,也將清理的東西,在TearDown中,與相同的結果

回答

1

我建議把所有的測試成擴展TestCase,然後在拆卸方法添加在UnsetStubs測試類:

from unittest import TestCase 
import mox 

class MyTestCasee(TestCase): 
    def __init__(self, testCaseName): 
    self.m = mox.Mox() 
    TestCase.__init__(self, testCaseName) 

    def tearDown(self): 
    self.m.UnsetStubs() 


def test_main_returnsUnknown_ifCalculator_returnsMinus1(self): 
    self.m.StubOutWithMock(check_es_insert,"getArgs") 
    check_es_insert.getArgs(\ 
    'Nagios plugin for checking the total number of documents stored in Elasticsearch')\ 
    .AndReturn({ 'critical' : 7, 'warning' : 5, 'address' : 'myhost:1234', 'file' : '/tmp/bla'}) 
    ################ 
    #some other mocking here, not relevant, I think 
    ################ 
    self.m.ReplayAll() 
    #now let's test 
    check_es_docs.main() 
    #verify and cleanup 
    self.m.VerifyAll() 
def test_main_doesWhatPrintAndExitSays_inNormalConditions(self): 
    self.m.StubOutWithMock(check_es_insert,"getArgs") 
    check_es_insert.getArgs(\ 
     'Nagios plugin for checking the total number of documents stored in Elasticsearch')\ 
     .AndReturn({ 'critical' : 7, 'warning' : 5, 'address' : 'myhost:1234', 'file' : '/tmp/bla'}) 
    ################ 
    #some other mocking here, not relevant, I think 
    ################ 
    self.m.ReplayAll() 
    #now let's test 
    check_es_docs.main() 
    #verify and clean up 
    self.m.VerifyAll() 
    self.m.ResetAll() 
+0

這絕對精彩,謝謝! 「__init__」事情做到了。我在開始時採用了相同的方法,而不是在那裏寫的「__init__」:'def setUp(self): self.mox = mox.Mox()'。現在我用你所說的取代了這個,我不再有「連鎖故障」。你能解釋爲什麼會發生?因爲對我來說這兩種方法看起來都一樣。 –

+0

我使用setUp(),它一直工作得很好。 – 2013-10-06 17:17:14

0

您還可以使用mox.MoxTestBase,其中規定了self.mox和在tearDown上調用VerifyAll()。

class ClassTestTest(mox.MoxTestBase): 
    def test(): 
    m = self.mox.CreateMockAnything() 

    m.something() 
    self.mox.ReplayAll() 
    m.something() # If this line is removed the test will fail