assertEqual只显示差异

时间:2014-08-26 18:16:08

标签: unit-testing python-2.7 assert

在Python 2.7中,我使用assertEqual来比较两个字符串。

但在某些情况下,我有很长的字符串,我希望assertEqual只显示差异,而不是完整的字符串。

为此,我使用difflib,就像那样

    import difflib
    #...
    diff = difflib.unified_diff(
        string1.splitlines(True),
        string2.splitlines(True),
        n=0
    )

    diff = ''.join(diff)

    self.assertEqual('', diff, msg=diff)

是否有一些assert*方法呢?

1 个答案:

答案 0 :(得分:3)

assertMultiLineEqual,它会将字符串的差异打印到完整的字符串中:

import unittest
import difflib

class MyTestCase(unittest.TestCase):
    def test_a(self):
        a = """hi
there
ok"""
        b = """bye
there
ok
whatever"""
        self.assertMultiLineEqual(a,b)

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

输出:

F
======================================================================
FAIL: test_a (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "ut.py", line 27, in test_a
    self.assertMultiLineEqual(a,b)
AssertionError: 'hi\nthere\nok' != 'bye\nthere\nok\nwhatever'
- hi
+ bye
  there
- ok+ ok
?   +
+ whatever

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)

根据文档,当您使用字符串参数调用assertEqual时,实际上应该会自动调用它,但实际上只有在传入 unicode 字符串时才会调用它。您可以使用addTypeEqualityFuncstr注册assertMutiLineEqual类型来解决此问题。然后,您的所有测试用例都可以使用assertEqual,并且仍然会获得差异行为:

import unittest

class MyTestCase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(MyTestCase, self).__init__(*args, **kwargs)
        self.addTypeEqualityFunc(str, self.assertMultiLineEqual)

    def test_a(self):
        a = """hi
there
ok"""
        b = """bye
there
ok
whatever"""
        self.assertEqual(a,b)  # Will actually call self.assertMultiLineEqual

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

如果想要看到diff,而不是除了diff之外的完整字符串,你可以子类unittest.TestCase并添加一个执行所需格式化的断言方法:

import unittest
import difflib

class _BaseTestCase(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(MyTestCase, self).__init__(*args, **kwargs)
        self.addTypeEqualityFunc(str, self.assertEqualWithDiff)

    def assertEqualWithDiff(self, left, right, msg=None):
        try:
            self._baseAssertEqual(left, right)
        except self.failureException:
            diff = difflib.unified_diff(
                left.splitlines(True),
                right.splitlines(True),
                n=0 
            )   
            diff = ''.join(diff)
            raise self.failureException("\n" + diff)

class MyTestCase(_BaseTestCase):   
    def test_a(self):
        a = """hi
there
ok"""
        b = """bye
there
ok
whatever"""
        self.assertEqual(a,b)  # This will actually call assertEqualWithDiff    

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

输出:

F
======================================================================
FAIL: test_a (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "ut.py", line 26, in test_a
    self.assertEqualWithDiff(a,b)
  File "ut.py", line 15, in assertEqualWithDiff
    raise self.failureException("\n" + diff)
AssertionError: 
--- 
+++ 
@@ -1 +1 @@
-hi
+bye
@@ -3 +3,2 @@
-ok+ok
+whatever

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)