[TIP] doctest with nested dictionaries

Graham Carlyle graham.carlyle at maplecroft.net
Thu Jul 5 03:35:55 PDT 2007


Hi

I've been testing some code with doctest recently and am wondering whats
the best way to proceed with a deeply nested data structure.

I've got some functions that return a nested data structure of lists &
dictionaries (django-amf views)

    >>> def foo(request):
    ...     return dict(name="bob", children=[dict(name="mary",
children=[])])

I could just do a simple comparison:

    >>> foo(None) == dict(name="bob", children=[dict(name="mary",
children=[])])
    True

but if it fails the error message isn't very helpful about whats wrong.

so as an alternative:

    >>> def areEqual(a, b):
    ...     if a == b:
    ...        return True
    ...     else:
    ...        return False, "%r != %r" % (a, b)

    >>> areEqual(foo(None), dict(name="bob", children=[]))
    (False, "{'children': [{'children': [], 'name': 'mary'}], 'name':
'bob'} != {'children': [], 'name': 'bob'}")

but that seems a retrograde step :) as the testing infrastructure is
getting in the way

Another way of solving this would be to pformat the output to normalise
it so:

    >>> from pprint import pformat
    >>> pformat(foo(None))
    "{'children': [{'children': [], 'name': 'mary'}], 'name': 'bob'}"

and for other parts of the response that may be dynamic substitute
placeholders...

    >>> bobs_child = "mary"
    >>> response_str = pformat(foo(None))
    >>> response_str.replace(bobs_child, "<bobs child>")
    "{'children': [{'children': [], 'name': '<bobs child>'}], 'name':
'bob'}"

however i was wondering whether the lack of the pformat normalisation as
a standard doctest option indicated that this is not considered a good
practice in using doctest. Also this seems similar to the assertEquals
solution in that the testing infrastructure is getting in the way.

A purer doctest option seems to be to break the datastructure apart and
compare it bit by bit but that would seem less readable and more
verbose.

    >>> response = foo(None)
    >>> type(response)
    <type 'dict'>
    >>> response["name"] 
    'bob'
    >>> children = response["children"] 

    ...etc...

Any opinions welcomed!

thanks,
Graham





More information about the testing-in-python mailing list