How do I test dictionary-equality with Python's doctest-package?

前端 未结 7 1469
眼角桃花
眼角桃花 2020-12-09 07:15

I\'m writing a doctest for a function that outputs a dictionary. The doctest looks like

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


        
相关标签:
7条回答
  • 2020-12-09 07:52

    turn it into a list via dict.items() and then sort it ...

    >>> l = my_function().items()
    >>> l.sort()
    >>> l
    [('a', 'dictionary'), ('this', 'is')]
    
    0 讨论(0)
  • 2020-12-09 07:54

    I found it useful to use the deepdiff package in my doctests when testing arbitrarily nested data. For example:

    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}}
    
    0 讨论(0)
  • 2020-12-09 07:57

    I ended up using this. Hacky, but it works.

    >>> p = my_function()
    >>> {'this': 'is', 'a': 'dictionary'} == p
    True
    
    0 讨论(0)
  • 2020-12-09 08:01

    You can create an instance of unittest.TestCase class inside your doctests, and use it to compare dictionaries:

    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'}
    

    Note: this approach is better than simply checking if dictionaries are equal, because it will show diff between the two dictionaries.

    0 讨论(0)
  • 2020-12-09 08:03

    Another good way is to use pprint (in the standard library).

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

    According to its source code, it's sorting dicts for you:

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

    items = _sorted(object.items())
    
    0 讨论(0)
  • 2020-12-09 08:13

    Doctest doesn't check __repr__ equality, per se, it just checks that the output is exactly the same. You have to ensure that whatever is printed will be the same for the same dictionary. You can do that with this one-liner:

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

    Although this variation on your solution might be cleaner:

    >>> my_function() == {'this': 'is', 'a': 'dictionary'}
    True
    
    0 讨论(0)
提交回复
热议问题