python - Python单元测试中多行字符串的比较

标签 python unit-testing unicode

当我在 Python 单元测试中比较两个 Unicode 字符串时,它会给出一条很好的失败消息,突出显示哪些行和字符不同。然而,比较两个 8 位字符串只是显示两个字符串,没有突出显示。

如何获得 Unicode 和 8 位字符串的高亮显示?

这是一个显示两个比较的示例单元测试:

import unittest

class TestAssertEqual(unittest.TestCase):
    def testString(self):
        a = 'xax\nzzz'
        b = 'xbx\nzzz'
        self.assertEqual(a, b)

    def testUnicode(self):
        a = u'xax\nzzz'
        b = u'xbx\nzzz'
        self.assertEqual(a, b)

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

这个测试的结果显示了差异:

FF
======================================================================
FAIL: testString (__main__.TestAssertEqual)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/data/don/workspace/scratch/scratch.py", line 7, in testString
    self.assertEqual(a, b)
AssertionError: 'xax\nzzz' != 'xbx\nzzz'

======================================================================
FAIL: testUnicode (__main__.TestAssertEqual)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/data/don/workspace/scratch/scratch.py", line 12, in testUnicode
    self.assertEqual(a, b)
AssertionError: u'xax\nzzz' != u'xbx\nzzz'
- xax
?  ^
+ xbx
?  ^
  zzz

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=2)

Python 3 更新

在 Python 3 中,字符串文字默认是 Unicode,所以这几乎是无关紧要的。 assertMultiLineEqual()不再支持字节字符串,因此您几乎只能使用常规 assertEqual()除非您愿意将字节字符串解码为 Unicode。

最佳答案

稍微挖掘一下 Python source code表明 TestCase 注册了一堆方法来测试不同类型的相等性。

self.addTypeEqualityFunc(dict, 'assertDictEqual')
self.addTypeEqualityFunc(list, 'assertListEqual')
self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
self.addTypeEqualityFunc(set, 'assertSetEqual')
self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
try:
    self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
except NameError:
    # No unicode support in this build
    pass

您可以看到 unicode 已注册使用 assertMultiLineEqual(),但 str 未注册任何特殊内容。我不知道为什么 str 被遗漏了,但到目前为止,我对以下两种方法中的任何一种都很满意。

直接调用

如果 8 位字符串未注册为默认使用 assertMultiLineEqual(),您仍然可以直接调用它。

def testString(self):
    a = 'xax\nzzz'
    b = 'xbx\nzzz'
    self.assertMultiLineEqual(a, b)

注册字符串类型

您也可以自己注册。只需在测试用例的 setUp() 方法中添加一行。做一次,你所有的测试方法都会使用正确的方法来测试相等性。如果您的项目有一个用于所有测试用例的公共(public)基类,那将是放置它的好地方。

class TestAssertEqual(unittest.TestCase):
    def setUp(self):
        super(TestAssertEqual, self).setUp()
        self.addTypeEqualityFunc(str, self.assertMultiLineEqual)

    def testString(self):
        a = 'xax\nzzz'
        b = 'xbx\nzzz'
        self.assertEqual(a, b)

    def testUnicode(self):
        a = u'xax\nzzz'
        b = u'xbx\nzzz'
        self.assertEqual(a, b)

当字符串比较失败时,这两种方法中的任何一种都会包括突出显示。

关于python - Python单元测试中多行字符串的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32359402/

相关文章:

python - 在 PyPI 上更改包名称的大小写

python - 如何为python中的每个元素添加一个数字?

python - 使用元组键从 Dictionary[key1,key2] 中获取第一个键的列表

python - 列表中唯一字符串的最大值

javascript - 无法让 unicode 字符正确显示 - Javascript 和 HTML

python:unicode问题

pipe.communicate 的 Python 编码

c - 用于测试错误处理程序的错误 C 代码

unit-testing - RIA 开发中的测试驱动开发/集成测试

typescript - NestJS - 测试套件无法运行从 'src/article/article.entity' 找不到模块 'comment/comment.entity.ts'