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

时间:2015-09-02 17:20:19

标签: 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)

1 个答案:

答案 0 :(得分:7)

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()方法中添加一行。做一次,所有测试方法都将使用正确的方法来测试相等性。如果你的项目有一个适用于所有测试用例的公共基类,那么这将是一个很好的地方。

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)

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