title: Python: Comparing two JSON objects in pytest
body: <p>I have an API that returns this JSON response</p>
  
  <pre><code>{
      "message": "Staff name and password pair not match",
      "errors": {
          "resource": "Login",
          "field": "staff_authentication",
          "code": "invalid",
          "stack_trace": null
      }
  }
  </code></pre>
  
  <p>Using pytest, I want to build a copy of the JSON object and make sure it is exactly the same</p>
  
  <pre><code>import pytest
  import json
  from collections import namedtuple
  from flask import url_for
  from myapp import create_app
  
  @pytest.mark.usefixtures('client_class')
  class TestAuth:
  
      def test_login(self, client):
          assert client.get(url_for('stafflogin')).status_code == 405
          res = self._login(client, 'no_such_user', '123456')
          assert res.status_code == 422
          response_object = self._json2obj(res.data)
          assert response_object.message == 'Staff name and password pair not match'
          invalid_password_json = dict(message="Staff name and password pair not match",
                                      errors=dict(
                                          resource="Login",
                                          code="invalid",
                                          field="staff_authentication",
                                          stack_trace=None,)
                                      )
          assert self._ordered(response_object) == self._ordered(invalid_password_json)
  
      def _login(self, client, staff_name, staff_password):
          return client.post('/login',
              data=json.dumps(dict(staff_name=staff_name, staff_password=staff_password)),
              content_type='application/json',
              follow_redirects=True)
  
      def _json_object_hook(self, d): return namedtuple('X', d.keys())(*d.values())
      def _json2obj(self, data): return json.loads(data, object_hook=self._json_object_hook)
  
      def _ordered(self, obj):
          if isinstance(obj, dict):
              return sorted((k, self._ordered(v)) for k, v in obj.items())
          if isinstance(obj, list):
              return sorted(self._ordered(x) for x in obj)
          else:
              return obj
  </code></pre>
  
  <p><code>pytest</code> shows that the 2 objects are unequal. </p>
  
  <pre><code>&gt;       assert self._ordered(response_object) == self._ordered(invalid_password_json)
  E       AssertionError: assert X(message='St...k_trace=None)) == [('errors', [(...r not match')]
  E         At index 0 diff: 'Staff name and password pair not match' != ('errors', [('code', 'invalid'), ('field', 'staff_authentication'), ('resource', 'Login'), ('stack_trace', None)])
  E         Full diff:
  E         - X(message='Staff name and password pair not match', errors=X(resource='Login', field='staff_authentication', code='invalid', stack_trace=None))
  E         + [('errors',
  E         +   [('code', 'invalid'),
  E         +    ('field', 'staff_authentication'),
  E         +    ('resource', 'Login'),
  E         +    ('stack_trace', None)]),
  E         +  ('message', 'Staff name and password pair not match')]
  
  tests/test_app.py:31: AssertionError
  =========================== 1 failed in 0.22 seconds ===========================
  </code></pre>
  
  <p>How do I make the newly created JSON object to the same as the response?</p>