Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compare two nested data structures for unittesting?

For those who know perl, I'm looking for something similar to Test::Deep::is_deeply() in Python.

In Python's unittest I can conveniently compare nested data structures already, if I expect them to be equal:

self.assertEqual(os.walk('some_path'),
                 my.walk('some_path'),
                 "compare os.walk with my own implementation")

However, in the wanted test, the order of files in the respective sublist of the os.walk tuple shall be of no concern.

If it was just this one test it would be ok to code an easy solution. But I envision several tests on differently structured nested data. And I am hoping for a general solution.

I checked Python's own unittest documentation, looked at pyUnit, and at nose and it's plugins. Active maintenance would also be an important aspect for usage.

The ultimate goal for me would be to have a set of descriptive types like UnorderedIterable, SubsetOf, SupersetOf, etc which can be called to describe a nested data structure, and then use that description to compare two actual sets of data.

In the os.walk example I'd like something like:

comparison = OrderedIterable(
               OrderedIterable(
                 str,
                 UnorderedIterable(),
                 UnorderedIterable()
               )
             )

The above describes the kind of data structure that list(os.walk()) would return. For comparison of data A and data B in a unit test, the current path names would be cast into a str(), and the dir and file lists would be compared ignoring the order with:

self.assertDeep(A, B, comparison, msg)

Is there anything out there? Or is it such a trivial task that people write their own? I feel comfortable doing it, but I don't want to reinvent, and especially would not want to code the full orthogonal set of types, tests for those, etc. In short, I wouldn't publish it and thus the next one has to rewrite again...

like image 446
cfi Avatar asked Feb 11 '13 16:02

cfi


1 Answers

Not a solution, but the currently implemented workaround to solve the particular example listed in the question:

    os_walk = list(os.walk('some_path'))
    dt_walk = list(my.walk('some_path'))
    self.assertEqual(len(dt_walk), len(os_walk), "walk() same length")
    for ((osw, osw_dirs, osw_files), (dt, dt_dirs, dt_files)) in zip(os_walk, dt_walk):
        self.assertEqual(dt, osw, "walk() currentdir")
        self.assertSameElements(dt_dirs, osw_dirs, "walk() dirlist")
        self.assertSameElements(dt_files, osw_files, "walk() fileList")

As we can see from this example implementation that's quite a bit of code. As we can also see, Python's unittest has most of the ingredients required.

like image 115
cfi Avatar answered Nov 02 '22 14:11

cfi