dec*_*bot 7 python string testing unit-testing truncated
我正在为我的程序在python中进行单元测试,我想做一个assertEquals测试。
我的代码如下所示:
class UnitTest(unittest.TestCase):
def test_parser(self):
self.assertEquals(parser,"some long string", "String is not equal")
Run Code Online (Sandbox Code Playgroud)
但是,由于我的字符串太长,我得到了类似test [471个字符] 0!=测试[473个字符]的信息。我想看到两个字符串之间的确切区别是什么,而不是看到截断的字符串。
任何人都有一个想法如何解决这个问题?
Mar*_*ers 10
unittest.TestCase.assertEquals
尝试为您提供字符串中的实际差异,同时使文本适合您的屏幕。
为此,它会截断公共部分,因此通过用块替换它们来截断没有差异的部分[<count> chars]
:
>>> case.assertEqual('foo' * 200, 'foo' * 100 + 'bar' + 'foo' * 99)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
assertion_func(first, second, msg=msg)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1194, in assertMultiLineEqual
self.fail(self._formatMessage(msg, standardMsg))
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
raise self.failureException(msg)
AssertionError: 'foof[291 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo[255 chars]ofoo' != 'foof[291 chars]oofoobarfoofoofoofoofoofoofoofoofoofoofoofoofo[255 chars]ofoo'
Diff is 1819 characters long. Set self.maxDiff to None to see it.
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,两个字符串共享一个长前缀,通过用[291 chars]
两个前缀替换 291 个字符来缩短该前缀。它们还共享一个很长的后缀,通过将文本替换为[255 chars]
.
在实际中仍显示差异,就在中间。
当然,当您将差异设置得太长时,即使差异也会被截断:
>>> case.assertEqual('foo' * 200, 'foo' * 80 + 'bar' * 30 + 'foo' * 80)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
assertion_func(first, second, msg=msg)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1194, in assertMultiLineEqual
self.fail(self._formatMessage(msg, standardMsg))
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
raise self.failureException(msg)
AssertionError: 'foof[231 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo[315 chars]ofoo' != 'foof[231 chars]oofoobarbarbarbarbarbarbarbarbarbarbarbarbarba[285 chars]ofoo'
Diff is 1873 characters long. Set self.maxDiff to None to see it.
Run Code Online (Sandbox Code Playgroud)
在这里,常见的后缀开始不同,但差异的开头仍然可见,应该可以帮助您找出文本出错的地方。
如果这还不够,您可以增加或消除差异限制。将该TestCase.maxDiff
属性设置为更高的数字(默认为 8 * 80,80 行文本),或者将其设置None
为完全消除:
self.maxDiff = None
Run Code Online (Sandbox Code Playgroud)
请注意,除非您的字符串包含换行符,否则差异可能不可读:
AssertionError的: 'foof [231个字符] oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo [315个字符] ofoo'= 'foof [231个字符] oofoobarbarbarbarbarbarbarbarbarbarbarbarbarba [285个字符] ofoo' - foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo!?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ + foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarfoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在这种情况下,包装输入和输出文本可能更有用:
from textwrap import wrap
self.maxDiff = None
self.assertEquals(wrap(parser), wrap("some long string"), "String is not equal")
Run Code Online (Sandbox Code Playgroud)
只是为了让您获得更好、更易读的差异输出:
>>> from textwrap import wrap
>>> case.assertEqual(wrap('foo' * 200), wrap('foo' * 80 + 'bar' * 30 + 'foo' * 80))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
assertion_func(first, second, msg=msg)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1019, in assertListEqual
self.assertSequenceEqual(list1, list2, msg, seq_type=list)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1001, in assertSequenceEqual
self.fail(msg)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
raise self.failureException(msg)
AssertionError: Lists differ: ['foo[244 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoof'[336 chars]foo'] != ['foo[244 chars]oofoobarbarbarbarbarbarbarbarbarbarbarbarbarb'[306 chars]foo']
First differing element 3:
'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof'
'foofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarb'
['foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
'ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo',
- 'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
- 'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
+ 'foofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarb',
+ 'arbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarfoofoofoofoofoofoofo',
'ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo',
'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
- 'ofoofoofoofoofoofoofoofoofoofoofoofoofoo']
+ 'ofoofoofoo']
Run Code Online (Sandbox Code Playgroud)
要替换[... chars]
和[truncated]...
实际字符(无论多长,无论比较值的类型是什么),请将其添加到您的*_test.py
文件中:
if 'unittest.util' in __import__('sys').modules:
# Show full diff in self.assertEqual.
__import__('sys').modules['unittest.util']._MAX_LENGTH = 999999999
Run Code Online (Sandbox Code Playgroud)
事实上,正如其他答案所指出的那样,设置self.maxDiff = None
无济于事,它不会使[... chars]
消失。但是,此设置有助于显示其他类型的长差异,因此我的建议是同时进行。
小智 6
所以,我进入了这个问题,因为我遇到了一个问题,即我使用assertEqual()和'self.maxDiff = None'不会导致显示完整的输出。追溯到原来,因为两个对象的类型不同(一个是列表,一个是生成器),所以没有使用会利用'self.maxDiff'的代码路径。因此,如果遇到需要完整的diff且'self.maxDiff'无法正常工作的问题,请确保两个比较对象的类型相同。