Python 如何正确重写TestCase.assertEqual(),生成正确的堆栈跟踪?

Python 如何正确重写TestCase.assertEqual(),生成正确的堆栈跟踪?,python,python-3.x,python-2.7,unit-testing,stack-trace,Python,Python 3.x,Python 2.7,Unit Testing,Stack Trace,我正试图为这个问题提供一个清晰的答案 我希望改进投票最多和未被接受的答案: 我有这个答案的问题是,它迫使我在单元测试中使用try…catch。然后,我试图将try…catch逻辑封装在TestCase.assertEqual方法的重写中 到目前为止,一切顺利。我设法覆盖了TestCase.assertEqual方法,但是,显示的stacktrace是错误的 运行以下示例: 导入单元测试 导入回溯 类multipleasertionFailures(unittest.TestCase): 定义初始

我正试图为这个问题提供一个清晰的答案

我希望改进投票最多和未被接受的答案:

我有这个答案的问题是,它迫使我在单元测试中使用
try…catch
。然后,我试图将
try…catch
逻辑封装在
TestCase.assertEqual
方法的重写中

到目前为止,一切顺利。我设法覆盖了
TestCase.assertEqual
方法,但是,显示的stacktrace是错误的

运行以下示例:

导入单元测试
导入回溯
类multipleasertionFailures(unittest.TestCase):
定义初始化(self,*args,**kwargs):
self.verificationErrors=[]
超级(多重测量失败,自我)。\uuuuu初始化(*args,**kwargs)
def拆卸(自):
super(multipleasertionfailures,self).tearDown()的
如果自验证错误:
self.fail('\n\n'+'\n'.join(self.verificationErrors))
self.verificationErrors.clear()
def assertEqual(自我、目标、结果,msg=”“):
尝试:
super(multipleasertionfailures,self).assertEqual(目标、结果、消息)
除unittest.TestCase.failureException作为错误外:
stacktrace=traceback.format_exc()
#stacktrace=traceback.format_stack()
self.verificationErrors.append(“.join(stacktrace))
#类DummyTestCase(unittest.TestCase):
类DummyTestCase(MultipleAssertionFailures):
def设置(自):
self.maxDiff=None
super(DummyTestCase,self.setUp())
def拆卸(自):
super(DummyTestCase,self).tearDown()
def测试功能名称(自身):
自身资产质量(“var”、“bar”)
self.assertEqual(“1937”、“511”)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
unittest.main()
您得到了以下输出:

F
======================================================================
FAIL: test_function_name (__main__.DummyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\User\Downloads\test.py", line 36, in tearDown
    super(DummyTestCase, self).tearDown()
  File "D:\User\Downloads\test.py", line 15, in tearDown
    self.fail( '\n\n' + '\n'.join( self.verificationErrors ) )
AssertionError: 

Traceback (most recent call last):
  File "D:\User\Downloads\test.py", line 21, in assertEqual
    super( MultipleAssertionFailures, self ).assertEqual( goal, results, msg )
  File "F:\Python\lib\unittest\case.py", line 844, in assertEqual
    assertion_func(first, second, msg=msg)
  File "F:\Python\lib\unittest\case.py", line 1228, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "F:\Python\lib\unittest\case.py", line 685, in fail
    raise self.failureException(msg)
AssertionError: 'var' != 'bar'
- var
? ^
+ bar
? ^
 : 

Traceback (most recent call last):
  File "D:\User\Downloads\test.py", line 21, in assertEqual
    super( MultipleAssertionFailures, self ).assertEqual( goal, results, msg )
  File "F:\Python\lib\unittest\case.py", line 844, in assertEqual
    assertion_func(first, second, msg=msg)
  File "F:\Python\lib\unittest\case.py", line 1228, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "F:\Python\lib\unittest\case.py", line 685, in fail
    raise self.failureException(msg)
AssertionError: '1937' != '511'
- 1937
+ 511
 : 
在输出中,您会注意到所显示的两个stacktrace是错误的,因为它们不反映单元测试代码所在的位置,而只反映my assertion代码所在的位置。通过在最小示例上注释
类DummyTestCase(multipleasertionfailures)
并取消注释
类DummyTestCase(unittest.TestCase)
,您将看到stacktrace的正确输出应该是:

F
======================================================================
FAIL: test_function_name (__main__.DummyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\User\Downloads\test.py", line 39, in test_function_name
    self.assertEqual( "var", "bar" )
AssertionError: 'var' != 'bar'
- var
? ^
+ bar
? ^
这个stacktrace(内置的)正确地指向test\u function\u name中的第39行
test.py”。我试着查看
TestCase
,但我不知道它是如何产生这个有意义的stacktrace的

或者,取消注释行
stacktrace=traceback.format_exc()
,我们可以得到一个真正完整的stacktrace:

F
======================================================================
FAIL: test_function_name (__main__.DummyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\User\Downloads\test.py", line 36, in tearDown
    super(DummyTestCase, self).tearDown()
  File "D:\User\Downloads\test.py", line 15, in tearDown
    self.fail( '\n\n' + '\n'.join( self.verificationErrors ) )
AssertionError: 

  File "D:\User\Downloads\test.py", line 43, in <module>
    unittest.main()
  File "F:\Python\lib\unittest\main.py", line 101, in __init__
    self.runTests()
  File "F:\Python\lib\unittest\main.py", line 271, in runTests
    self.result = testRunner.run(self.test)
  File "F:\Python\lib\unittest\runner.py", line 176, in run
    test(result)
  File "F:\Python\lib\unittest\suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\suite.py", line 122, in run
    test(result)
  File "F:\Python\lib\unittest\suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\suite.py", line 122, in run
    test(result)
  File "F:\Python\lib\unittest\case.py", line 668, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\case.py", line 620, in run
    testMethod()
  File "D:\User\Downloads\test.py", line 39, in test_function_name
    self.assertEqual( "var", "bar" )
  File "D:\User\Downloads\test.py", line 25, in assertEqual
    stacktrace = traceback.format_stack()

  File "D:\User\Downloads\test.py", line 43, in <module>
    unittest.main()
  File "F:\Python\lib\unittest\main.py", line 101, in __init__
    self.runTests()
  File "F:\Python\lib\unittest\main.py", line 271, in runTests
    self.result = testRunner.run(self.test)
  File "F:\Python\lib\unittest\runner.py", line 176, in run
    test(result)
  File "F:\Python\lib\unittest\suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\suite.py", line 122, in run
    test(result)
  File "F:\Python\lib\unittest\suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\suite.py", line 122, in run
    test(result)
  File "F:\Python\lib\unittest\case.py", line 668, in __call__
    return self.run(*args, **kwds)
  File "F:\Python\lib\unittest\case.py", line 620, in run
    testMethod()
  File "D:\User\Downloads\test.py", line 40, in test_function_name
    self.assertEqual( "1937", "511" )
  File "D:\User\Downloads\test.py", line 25, in assertEqual
    stacktrace = traceback.format_stack()
F
======================================================================
失败:测试函数名(\uuuuu main\uuuu.DummyTestCase)
----------------------------------------------------------------------
回溯(最近一次呼叫最后一次):
文件“D:\User\Downloads\test.py”,第36行,拆卸
super(DummyTestCase,self).tearDown()
文件“D:\User\Downloads\test.py”,第15行,拆卸
self.fail('\n\n'+'\n'.join(self.verificationErrors))
断言者错误:
文件“D:\User\Downloads\test.py”,第43行,在
unittest.main()
文件“F:\Python\lib\unittest\main.py”,第101行,在\uuu init中__
self.runTests()
runTests中第271行的文件“F:\Python\lib\unittest\main.py”
self.result=testRunner.run(self.test)
文件“F:\Python\lib\unittest\runner.py”,第176行,正在运行
测试(结果)
调用中第84行的文件“F:\Python\lib\unittest\suite.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\suite.py”,第122行,正在运行
测试(结果)
调用中第84行的文件“F:\Python\lib\unittest\suite.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\suite.py”,第122行,正在运行
测试(结果)
调用中第668行的文件“F:\Python\lib\unittest\case.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\case.py”,第620行,正在运行
testMethod()
文件“D:\User\Downloads\test.py”,第39行,测试函数名称
自身资产质量(“var”、“bar”)
文件“D:\User\Downloads\test.py”,第25行,在assertEqual中
stacktrace=traceback.format_stack()
文件“D:\User\Downloads\test.py”,第43行,在
unittest.main()
文件“F:\Python\lib\unittest\main.py”,第101行,在\uuu init中__
self.runTests()
runTests中第271行的文件“F:\Python\lib\unittest\main.py”
self.result=testRunner.run(self.test)
文件“F:\Python\lib\unittest\runner.py”,第176行,正在运行
测试(结果)
调用中第84行的文件“F:\Python\lib\unittest\suite.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\suite.py”,第122行,正在运行
测试(结果)
调用中第84行的文件“F:\Python\lib\unittest\suite.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\suite.py”,第122行,正在运行
测试(结果)
调用中第668行的文件“F:\Python\lib\unittest\case.py”__
返回自运行(*args,**kwds)
文件“F:\Python\lib\unittest\case.py”,第620行,正在运行
testMethod()
文件“D:\User\Downloads\test.py”,第40行,测试函数名称
self.assertEqual(“1937”、“511”)
文件“D:\User\Downloads\test.py”,第25行,在assertEqual中
stacktrace=traceback.format_stack()
我怎么能像内置的
TestCase.assertEqual那样总是把这个完整的stacktrace切断成有意义的东西呢?

我刚刚发布了一些我在原始问题上为这个构建的东西。我刚刚发布了一些我在原始问题上为这个构建的东西。