Python: Using JSON or pprint to compare complex data structuresΒΆ
abstract: | JSON or pprint can convert various complex data structures into printable text for user display. Your tests can convert your data to a printable format and diff the results to make a comparison. |
---|
We have various systems that contain nested trees of lists and dicts. You can display these data items with python builtins.
JSON makes a very readable format, but it does not represent every possible python object. pprint makes a slightly less readable format, but knows (for example) the difference between tuples and lists.
Using json:
import json
# to a string
s = json.dumps( mydata, indent=4, sort_keys=True, default=str )
# to a file
f=open("out/myfile.txt","w")
json.dump( mydata, f, indent=4, sort_keys=True, default=str )
pprint understands python objects better, but is harder to read.
Using pprint:
import pprint
# to a string
s = pprint.pformat( mydata, indent=4 )
# to a file
f=open("out/myfile.txt","w")
pprint.pprint( mydata, stream=f, indent=4 )
Once you have the object in a string or file, you can use various diff-like tools to compare it.
This example uses difflib and json. The reference data is a string constant in the source code.
import json
import pandokia.helpers.filecomp as filecomp
l = [ { 'a' : 1, 'b' : 2 }, [ 1, 2 ] ]
result = json.dumps( l, indent=4, sort_keys=True, default=str )
print result
ref = """
[
{
"a": 1,
"b": 2
},
[
1,
2
]
]
"""
assert filecomp.diffjson( result, ref )
This example creates an output file and compares to a reference file. You can update the reference file by using the okify feature in the gui.
import os.path
import json
import pandokia.helpers.filecomp as filecomp
def test_1() :
global tda
tda = { }
# list of files to compare
files = [
( "test_1.txt", "diff", { 'rstrip' : True } )
]
# delete output files before running test
filecomp.delete_output_files( files )
# some data
l = [ { 'a' : 1, 'b' : 2 }, [ 1, 2 ] ]
# make the output file ( in directory out/ )
f = open("out/test_1.txt","w" )
result = json.dump( l, f, indent=4, sort_keys=True, default=str )
f.close()
# file comparison tool
filecomp.compare_files(
# files to compare
files,
# name to use to construct okfile
"okfile/" + os.path.basename(__file__) + ".test_1",
# tda dict (to record name of okfile)
tda
)