当前位置: 首页 > 知识库问答 >
问题:

当多行字符串的unittest失败时,PyCharm是否显示完全差异?

许博
2023-03-14

我正在使用“unittest”框架编写一些Python单元测试,并在PyCharm中运行它们。一些测试将长时间生成的字符串与从文件中读取的参考值进行比较。如果比较失败,我希望使用PyCharms diff查看器查看两个比较字符串的差异。

所以代码是这样的:

    actual = open("actual.csv").read()
    expected = pkg_resources.resource_string('my_package', 'expected.csv').decode('utf8')
    self.assertMultiLineEqual(actual, expected)

PyCharm很好地将测试识别为失败,并在结果窗口中提供了一个链接以单击打开diff查看器。但是,由于unittest如何缩短结果,我在diff查看器中得到了这样的结果:

左:

'时间[57 个字符]0;1;1;1;1;1;1;1;1 0;2;1;3;4;2;3;1 0;3;[110 字符]32 '

右侧:

time[57 chars]ercen 0;1;1;1;1;1;1;1 0;2;1;3;4;2;3;1 0;3;2[109 chars]32 '

现在,我想摆脱所有 [X 字符] 部分,只看到整个文件和 PyCharm 完全可视化的实际差异。

我试图查看 unittest 代码,但找不到打印完整结果的配置选项。有一些变量,如 maxDiff 和 _diffThreshold但它们对此打印没有影响。

此外,我试图在py.test中运行它,但在PyCharm中的支持甚至更少(甚至没有链接到失败的测试)。

有没有一些技巧使用unittest的分散包,或者其他一些技巧使用另一个Python测试框架来做到这一点?

共有3个答案

丁勇
2023-03-14

这里一个相关的问题是< code>unittest。test case . assertmultilineequal 是用< code>difflib.ndiff()实现的。这产生了非常大的差异,包含了所有的共享内容以及差异。如果您使用< code > difflib . unified _ diff()作为替代,您将获得更小的差异,这种差异很少被截断。这通常避免了设置maxDiff的需要。

import unittest
from unittest.case import _common_shorten_repr
import difflib


def assertMultiLineEqual(self, first, second, msg=None):
    """Assert that two multi-line strings are equal."""
    self.assertIsInstance(first, str, 'First argument is not a string')
    self.assertIsInstance(second, str, 'Second argument is not a string')

    if first != second:
        firstlines = first.splitlines(keepends=True)
        secondlines = second.splitlines(keepends=True)
        if len(firstlines) == 1 and first.strip('\r\n') == first:
            firstlines = [first + '\n']
            secondlines = [second + '\n']
        standardMsg = '%s != %s' % _common_shorten_repr(first, second)
        diff = '\n' + ''.join(difflib.unified_diff(firstlines, secondlines))
        standardMsg = self._truncateMessage(standardMsg, diff)
        self.fail(self._formatMessage(msg, standardMsg))

unittest.TestCase.assertMultiLineEqual = assertMultiLineEqual
宋俊民
2023-03-14

嗯,为了我的测试目的,我设法绕过了这个问题。我没有使用unittest中的addt平等方法,而是编写了我自己的方法,并在unittest测试用例中使用它。失败时,它会给我全文,PyCharm差异查看器也会正确显示完整的差异。

我的assert语句位于自己的模块(t_assert.py)中,如下所示

def equal(expected, actual):
    msg = "'"+actual+"' != '"+expected+"'"
    assert expected == actual, msg

在我的测试中,我这样调用它

    def test_example(self):
        actual = open("actual.csv").read()
        expected = pkg_resources.resource_string('my_package', 'expected.csv').decode('utf8')
        t_assert.equal(expected, actual)
        #self.assertEqual(expected, actual)

到目前为止似乎有效。。

裴永年
2023-03-14

TestCase.maxDiff=无在许多地方给出的答案只确保unittest输出中显示的diff是全长的。为了在

import unittest

# Show full diff in unittest
unittest.util._MAX_LENGTH=2000

来源:https://stackoverflow.com/a/23617918/1878199

 类似资料:
  • 问题内容: 我想打印一个字符或字符串,例如’-‘n次。 我可以不使用循环就做吗? ..这意味着打印3次,如下所示: 问题答案: Python 2.x: Python 3.x:

  • 我有一个注册过程,在确认细节上,我正在尝试显示输入的地址,但我似乎不能让它正确显示,我已经尝试了网站上的其他答案,但没有一个似乎是有效的。 代码 HTML 理想情况下,我希望使用,但最初我尝试了一下,找到的答案是使用 这是,它正在填充我的“comp add”。 当用户离开页面时,它会这样做,并按上面所示工作,但我无论如何都无法将其显示为: 添加第1行 添加第2行 城镇 县 BB1 1BB

  • 我已经在谷歌上搜索了我能想到的这个问题的所有变体,但我只是收到了关于失败服务的问题,而不是systemctl如何处理它们的问题。我有一个服务,我一直在以init. d脚本的形式运行。我们现在使用systemctl,很好。我创建了一个服务文件,它是由systemd-sysv生成器自动生成的文件的轻微修改版本。对于ExecStart和ExecStop,它调用一个bash脚本,如果启动/停止成功,它返回

  • 问题内容: 为什么: 产生错误? 如果它刚返回就不会更合逻辑吗? 问题答案: 由于空字符串不是有效的JSON,因此返回不正确,因为它是有效的JSON。例如 返回。无效的JSON也被解析为null将是一个错误。 空字符串不是有效的JSON,两个引号是有效的JSON。这是一个重要的区别。 也就是说,包含两个引号的字符串与空字符串不同。 将正确解析(返回一个空字符串)。但 将不会。 有效的最小JSON字

  • 问题内容: 我有一个字符串,其中单词“ LOCAL”多次出现。我使用该函数搜索该单词,但它也返回另一个单词“ Locally”。我如何准确匹配“本地”一词? 问题答案: 对于这种事情,正则表达式非常有用: \ b基本上表示单词边界。可以是空格,标点符号等。 编辑评论: 显然,如果您不想忽略这种情况,则可以删除flags = re.IGNORECASE。

  • 我有一个测试: 由于是404而不是409,所以当前的情况就会崩溃。我希望测试失败,但整个测试套件却因为未捕获的异常而停止。我如何捕获异常(并使测试失败)并阻止它破坏所有其他测试? 这是我运行上面的代码时得到的输出: 问候奥斯卡