【问题标题】:Why does a failing test with mox fail other tests as well?为什么使用 mox 的失败测试也会失败其他测试?
【发布时间】:2012-06-09 15:24:31
【问题描述】:

我的问题很简单:我有一堆使用 pymox 的单元测试。当我添加一个失败的新测试时,大多数时候很多其他测试也会失败。我怎样才能防止这种情况发生?

例如,我有一个简单的脚本,我有两个单元测试:

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() 之后,结果相同
  • 我尝试从 SetUp 方法初始化 mox.Mox() 对象,并将清理内容放入 TearDown,结果相同

【问题讨论】:

    标签: unit-testing mox


    【解决方案1】:

    我建议将所有测试放入扩展 TestCase 的测试类中,然后在 tearDown 方法中添加 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()
    

    【讨论】:

    • 这真是太棒了,谢谢! "init" 事情做到了。一开始我有同样的方法,只是我没有你在那里写的“init”:`def setUp(self): self.mox = mox.Mox()`。现在我用你所说的替换了它,我不再遇到“链故障”了。你能解释为什么会这样吗?因为在我看来,这两种方法看起来都一样。
    【解决方案2】:

    你也可以使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-04
      • 2016-06-23
      • 2021-01-06
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 2021-01-28
      相关资源
      最近更新 更多