如何在Python中执行断言内省

时间:2016-11-18 17:23:52

标签: python assert pytest

我正在研究如何在Python中执行断言内省,方式与that py.test does相同。例如......

>>> a = 1
>>> b = 2
>>> assert a == b
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AssertionError   # <--- I want more information here, eg 'AssertionError: 1 != 2'

我看到py.codehas some functionality around this并且我也看到了this answer,并指出sys.excepthook允许您插入您想要的异常行为,但我不清楚如何将它们放在一起。

3 个答案:

答案 0 :(得分:1)

如果要显示详细的错误消息,可以执行此类操作

def assertion(a,b):
    try:
        assert a==b
    except AssertionError as e:
        e.args += ('some other', 'information',)
        raise

a=1
b=2
assertion(a,b)

此代码将提供此输出:

Traceback (most recent call last):
  File "tp.py", line 11, in <module>
    assertion(a,b)
  File "tp.py", line 4, in assertion
    assert a==b
AssertionError: ('some other', 'information')

答案 1 :(得分:1)

unittest断言提供额外信息(可能超出您的需要)。灵感来自Raymond Hettinger的talk。 这是一个部分答案,只给出了ab(输出的最后一行)的值,而不是pytest中您唯一要求的额外内省。

import unittest

class EqualTest(unittest.TestCase):

    def testEqual(self, a, b):
        self.assertEqual(a, b)


a, b = 1, 2
assert_ = EqualTest().testEqual
assert_(a, b)

输出

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-4-851ce0f1f668> in <module>()
      9 a, b = 1, 2
     10 assert_ = EqualTest().testEqual
---> 11 assert_(a, b)

<ipython-input-4-851ce0f1f668> in testEqual(self, a, b)
      4 
      5     def testEqual(self, a, b):
----> 6         self.assertEqual(a, b)
      7 
      8 

C:\Anaconda3\lib\unittest\case.py in assertEqual(self, first, second, msg)
    818         """
    819         assertion_func = self._getAssertEqualityFunc(first, second)
--> 820         assertion_func(first, second, msg=msg)
    821 
    822     def assertNotEqual(self, first, second, msg=None):

C:\Anaconda3\lib\unittest\case.py in _baseAssertEqual(self, first, second, msg)
    811             standardMsg = '%s != %s' % _common_shorten_repr(first, second)
    812             msg = self._formatMessage(msg, standardMsg)
--> 813             raise self.failureException(msg)
    814 
    815     def assertEqual(self, first, second, msg=None):

AssertionError: 1 != 2

答案 2 :(得分:0)

我认为在独立环境中重现pytest的断言内省并不容易。文档包含更多details的工作原理:

  pytest会在导入时重写测试模块。它通过使用导入钩子来编写新的pyc文件来做到这一点。在大多数情况下,这是透明的。但是,如果您自己弄乱了导入,则导入挂钩可能会造成干扰。如果是这种情况,只需使用--assert = reinterp或--assert = plain。此外,如果无法写入新的pycs,即在只读文件系统或zipfile中,则重写将以静默方式失败。

要在任意模块中运行该功能,似乎需要大量的技巧,因此您最好使用其他答案中建议的解决方案。