当前位置: 首页 > 面试题库 >

如何在Python2.7的unittest中显示由assertRaises()捕获的错误消息?

匡翰
2023-03-14
问题内容

为了确保来自我的模块的错误消息是有用的,我想查看assertRaises()捕获的所有错误消息。今天,我对每个assertRaises()都这样做,但是由于测试代码中有很多代码,因此变得非常乏味。

如何打印所有assertRaises()的错误消息?我研究了http://docs.python.org/library/unittest.html上的文档,但没有弄清楚如何解决它。我可以以某种方式猴子对assertRaises()方法进行修补吗?我宁愿不更改测试代码中的所有assertRaises()行,因为我最经常以标准方式使用测试代码

我今天就是这样做的。例如:

#!/usr/bin/env python

def fail():
    raise ValueError('Misspellled errrorr messageee')

和测试代码:

#!/usr/bin/env python
import unittest
import failure

class TestFailureModule(unittest.TestCase):

    def testFail(self):
        self.assertRaises(ValueError, failure.fail)

if __name__ == '__main__':
    unittest.main()

要检查错误消息,我只需将assertRaises()中的错误类型更改为例如IOError。然后我可以看到错误消息:

 E
======================================================================
ERROR: testFail (__main__.TestFailureModule)
----------------------------------------------------------------------
Traceback (most recent call last):
 File "test_failure.py", line 8, in testFail
   self.assertRaises(IOError, failure.fail)
  File "/usr/lib/python2.7/unittest/case.py", line 471, in assertRaises
    callableObj(*args, **kwargs)
 File "/home/jonas/Skrivbord/failure.py", line 4, in fail
    raise ValueError('Misspellled errrorr messageee')
ValueError: Misspellled errrorr messageee

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

有什么建议?/乔纳斯

编辑:

在罗伯特·罗斯尼的提示下,我设法解决了这个问题。它主要不是用于拼写错误,而是用于确保错误消息对于模块用户而言确实有意义。通过设置SHOW_ERROR_MESSAGES
= False,可以实现单元测试的正常功能(这是我大多数时候的用法)。

我仅重写assertRaises()方法,如下所示。它就像魅力!

SHOW_ERROR_MESSAGES = True

class NonexistantError(Exception):
    pass

class ExtendedTestCase(unittest.TestCase):
    def assertRaises(self, excClass, callableObj, *args, **kwargs):
        if SHOW_ERROR_MESSAGES:
            excClass = NonexistantError
        try:
            unittest.TestCase.assertRaises(self, excClass, callableObj, *args, **kwargs)
        except:
            print '\n    ' + repr(sys.exc_info()[1])

结果输出的一部分:

testNotIntegerInput (__main__.TestCheckRegisteraddress) ... 
    TypeError('The registeraddress must be an integer. Given: 1.0',)

    TypeError("The registeraddress must be an integer. Given: '1'",)

    TypeError('The registeraddress must be an integer. Given: [1]',)

    TypeError('The registeraddress must be an integer. Given: None',)
ok
testCorrectNumberOfBytes (__main__.TestCheckResponseNumberOfBytes) ... ok
testInconsistentLimits (__main__.TestCheckNumerical) ... 
    ValueError('The maxvalue must not be smaller than minvalue. Given: 45 and 47, respectively.',)

    ValueError('The maxvalue must not be smaller than minvalue. Given: 45.0 and 47.0, respectively.',)
ok
testWrongValues (__main__.TestCheckRegisteraddress) ... 
    ValueError('The registeraddress is too small: -1, but minimum value is 0.',)

    ValueError('The registeraddress is too large: 65536, but maximum value is 65535.',)
ok
testTooShortString (__main__.TestCheckResponseWriteData) ... 
    ValueError("The payload is too short: 2, but minimum value is 4. Given: '\\x00X'",)

    ValueError("The payload is too short: 0, but minimum value is 4. Given: ''",)

    ValueError("The writedata is too short: 1, but minimum value is 2. Given: 'X'",)

    ValueError("The writedata is too short: 0, but minimum value is 2. Given: ''",)
ok
testKnownValues (__main__.TestCreateBitPattern) ... ok
testNotIntegerInput (__main__.TestCheckSlaveaddress) ... 
    TypeError('The slaveaddress must be an integer. Given: 1.0',)

    TypeError("The slaveaddress must be an integer. Given: '1'",)

    TypeError('The slaveaddress must be an integer. Given: [1]',)

    TypeError('The slaveaddress must be an integer. Given: None',)
ok

问题答案:

开箱即用unittest不会执行此操作。如果您想经常这样做,可以尝试如下操作:

class ExtendedTestCase(unittest.TestCase):

  def assertRaisesWithMessage(self, msg, func, *args, **kwargs):
    try:
      func(*args, **kwargs)
      self.assertFail()
    except Exception as inst:
      self.assertEqual(inst.message, msg)

从而ExtendedTestCase不是从派生单元测试类unittest.TestCase

但是,实际上,如果您只关心拼写错误的错误消息,并且足够关心要围绕它构建测试用例,则不应将消息内联为字符串文字。您应该对它们进行处理,就像对其他任何重要的字符串进行处理一样:在导入的模块中将它们定义为常量,并由他人负责校对。拼写错误的代码的开发人员也会在测试用例中拼错它们。



 类似资料:
  • 我正在尝试用spring显示一个报告PDF,我终于得到了它,但是问题出现在我的代码中有一个异常或错误的时候。在这种情况下,我想在我的应用程序中显示特殊的消息。sping控制器返回一个带有文件pdf的ResponseEntity和一个http状态代码。

  • 问题内容: 我正在尝试在我的一个课程中实现PHP5的类型提示, 正确用法: 产生错误: 可捕获的致命错误:传递给ClassA :: method_a()的参数1必须是ClassB的实例,给定ClassWrong的实例… 是否有可能捕获到该错误(因为它说“可捕获”)?如果是的话,如何? 问题答案: 更新:这不再是php 7中可捕获的致命错误。相反,抛出了“异常”。不是从Exception而是Erro

  • 问题内容: 如何在Liferay门户中显示错误消息?我在liferay.com网站上阅读了有关显示错误消息的信息,我可以使用标签库中的liferay- ui:error标签,但是它不起作用,如何使用它? 问题答案: 您对“ liferay-ui:error”标记是正确的,因此在JSP上,您将拥有: 然后,在Java代码中,通常将需要RenderRequest或ActionRequest,但是也可以

  • 问题内容: 我正在使用PHP函数将数据从本地计算机发布到Web服务器。我的代码如下: 不幸的是,我无法捕获任何错误,例如404、500或网络故障。那么,我如何得知数据没有发布到远程或从远程检索呢? 问题答案: 您可以使用该功能检测是否有错误。例如:

  • 我正在从可能被压缩的服务器下载内容,所以我使用了我在不同地方找到的样板: 问题是,如果HTTPS请求因网络错误而失败,我有时会引发以下异常: 该“错误”事件处理程序未捕获异常。那么我如何捕获它,以便能够正确地清理文件并知道如何重试?

  • 我有下面的代码,我用它来让一个用户静默登录 如果用户无法静默登录,将会导致错误。 我遇到的问题是,我似乎无法抓住例外。捕获错误或捕获块正在被击中。如何捕获此错误?