45

我正在为输出字典的函数编写文档测试。doctest 看起来像

>>> my_function()
{'this': 'is', 'a': 'dictionary'}

当我运行它时,它失败了

Expected:
    {'this': 'is', 'a': 'dictionary'}
Got:
    {'a': 'dictionary', 'this': 'is'}

关于这次失败的原因,我最好的猜测是 doctest 不是检查字典的相等性,而是__repr__相等性。这篇文章表明有一些方法可以欺骗 doctest 检查字典是否相等。我怎样才能做到这一点?

4

7 回答 7

40

另一个好方法是使用pprint(在标准库中)。

>>> import pprint
>>> pprint.pprint({"second": 1, "first": 0})
{'first': 0, 'second': 1}

根据其源代码,它正在为您排序字典:

http://hg.python.org/cpython/file/2.7/Lib/pprint.py#l158

items = _sorted(object.items())
于 2014-01-20T06:37:57.757 回答
30

Doctest 本身不检查__repr__相等性,它只是检查输出是否完全相同。您必须确保打印的任何内容对于同一个字典都是相同的。你可以用这个单线做到这一点:

>>> sorted(my_function().items())
[('a', 'dictionary'), ('this', 'is')]

尽管您的解决方案的这种变化可能更清晰:

>>> my_function() == {'this': 'is', 'a': 'dictionary'}
True
于 2013-03-21T14:04:09.800 回答
15

我最终使用了这个。哈克,但它的工作原理。

>>> p = my_function()
>>> {'this': 'is', 'a': 'dictionary'} == p
True
于 2013-03-21T14:01:32.817 回答
3

通过 dict.items() 将其转换为列表,然后对其进行排序...

>>> l = my_function().items()
>>> l.sort()
>>> l
[('a', 'dictionary'), ('this', 'is')]
于 2013-03-21T13:58:35.163 回答
2

大部分已经在这里说了..无论如何 JSYK:doctest 文档中有一个专门的部分:

https://docs.python.org/3.5/library/doctest.html#warnings

于 2017-05-04T12:37:03.187 回答
1

unittest.TestCase您可以在 doctests中创建一个类的实例,并使用它来比较字典:

def my_function(x):
    """
    >>> from unittest import TestCase
    >>> t = TestCase()

    >>> t.assertDictEqual(
    ...     my_function('a'),
    ...     {'this': 'is', 'a': 'dictionary'}
    ... )

    >>> t.assertDictEqual(
    ...     my_function('b'),
    ...     {'this': 'is', 'b': 'dictionary'}
    ... )

    """
    return {'this': 'is', x: 'dictionary'}

注意:这种方法比简单地检查字典是否相等要好,因为它会显示两个字典之间的差异。

于 2016-08-10T01:46:29.083 回答
0

我发现在测试任意嵌套数据时在我的文档测试中使用deepdiff包很有用。例如:

def something_complicated():
    """
    >>> from deepdiff import DeepDiff
    >>> DeepDiff(something_complicated(),
    ...          {'expected': {'output': ['a', 'b', 'c']}},
    ...          ignore_order=True)
    {}
    """
    items = ['a', 'b', 'c']
    random.shuffle(items)
    return {'expected': {'output': items}}
于 2019-11-10T18:52:05.173 回答