如何在Python中执行断言内省

如何在Python中执行断言内省,python,assert,pytest,Python,Assert,Pytest,我正在研究如何以同样的方式在Python中执行断言内省。例如 >>> 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 'Assertion

我正在研究如何以同样的方式在Python中执行断言内省。例如

>>> 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'
>a=1
>>>b=2
>>>断言a==b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在

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

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')
回溯(最近一次呼叫最后一次):
文件“tp.py”,第11行,在
断言(a,b)
断言中第4行的文件“tp.py”
断言a==b
AssertionError:(“其他”、“信息”)

unittest
断言提供了额外的信息(可能比您需要的更多)。灵感来源于雷蒙德·海廷格的作品。 这是一个部分答案,只给出了
a
b
(输出的最后一行)的值,而不是在
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
---------------------------------------------------------------------------
AssertionError回溯(上次最近的调用)
在()
9a,b=1,2
10断言=相等测试().testEqual
--->11(a,b)
在testEqual中(自我、a、b)
4.
5 def测试质量(自身、a、b):
---->6.自评资格(a、b)
7.
8.
C:\Anaconda3\lib\unittest\case.py在assertEqual中(self、first、second、msg)
818         """
819断言\u func=self.\u getAssertEqualityFunc(第一,第二)
-->820断言函数(第一,第二,msg=msg)
821
822 def assertNotEqual(自身、第一个、第二个,消息=None):
C:\Anaconda3\lib\unittest\case.py in_baseAssertEqual(self、first、second、msg)
811 standardMsg='%s!=%s%\u common\u shorten\u repr(第一、第二)
812 msg=self.\u formatMessage(msg,standardMsg)
-->813提升自失效异常(msg)
814
815 def assertEqual(自我、第一、第二、消息=无):
断言错误:1!=2

我认为在独立的上下文中重现pytest的断言内省并不容易。文档中还包含一些关于其工作原理的内容:

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


看起来要在任意模块中实现这一点需要相当多的技巧,因此您最好使用其他答案中建议的解决方案。

为什么不使用
pytest
本身?@pylang我对重复使用py.test中允许这种情况发生的部分没有问题,但我不能只使用py.test本身关于我的问题,我想你应该假设,例如,我并没有在这个上下文中运行测试。@pylang是否可以在一般上下文中使用pytest的assert?我假设OP希望在独立程序/库中使用该功能,例如,用于验证目的。我想我现在明白了。是的,我不相信pytes有交互功能e模式(至少不适用于jupyter笔记本电脑).传统上,我之所以使用
nose
,就是因为这个问题。@Tom.这有帮助吗?不是特别有帮助,不是,但还是很感激。这个答案为例外添加了其他信息,但我感兴趣的是比较本身的状态。在这种情况下,这意味着包括a和b的值并确定问题是它们不相等。(但这是一种通用方法,也值得其他运算符使用)谢谢,但在本例中,我特别感兴趣的是反省
assert
语句本身。