skip to Main Content

I’m writing a test in Cypress to compare 2 JSON files which are

  1. missing a few attributes
  2. not arranged in the same order
  3. having different values for the attributes

file 1

{
    "isActive": true,
    "isLocked": false,
    "phone": null,
    "details": [
      { 
       "firstName":"test1",
       "lastName": "last1",
       "userId": "testuser1",
       "lastLoggedIn": "2024-01-01"
      }
    ],
}   

file 2

{
    "isActive": true,
    "phone": 123-456-7890,
    "details": [
      { 
       "firstName":"test1",
       "userId": "testuser1",
       "lastLoggedIn": "2024-01-02"
      }
    ],
    "isLocked": false
}      

But when I use

cy.readFile('../src/cypress/fixtures/file1.json').then(file1 => cy.readFile('../src/cypress/fixtures/file2.json').should('deep.equal', file1))

it errors out at the first non matching attribute which are arranged in different order(but definitely are present in the json file). How do I only check for the missing attributes and the attributes with different values and print them to the console?

Expected Output:

 + expected - actual

      -   "phone": 123-456-7890,
          "details": [
          { 
      -    lastLoggedIn: "2024-01-02"
          }
         ]
--
      +   "phone": null,     
          "details": [
          { 
      +    lastName: "last1",
      +    lastLoggedIn: "2024-01-01"
          }
         ]

2

Answers


  1. I don’t know about cypress library but in nodejs you could just as easily parse the json file with JSON.parse into objects and complete the following steps

    Count number of shallow attributes in both objs
    Test the above attributes against each other for a difference
    If you wanted to ensure strict equality then also test each attribute for its data type
    When you encounter a nested object complete same steps above, best to put them into a reusable function

    Login or Signup to reply.
  2. Deep compare in JSON with Javascript is tricky, so much so there is evan a open issue on deep.equal in the offical cypress repository.

    https://github.com/cypress-io/cypress/issues/4084

    a common way to approach this is to use JSON.stringfy to convert the objects into strings then compare the strings. Or you could write a more comprehensive test that tests each property indiviually.

    Arguably JSON.stringfy is a heavy handed approach, you might see that comment around as you research it. But for a small blob in a unit test like your example this is perfectly fine.

    cy.readFile('../src/cypress/fixtures/file1.json').then(
     (file1) => {
         cy.readFile('../src/cypress/fixtures/file2.json').then((file2) => {
            const file1str = JSON.stringfy(file1)
            const file2str = JSON.stringfy(file2)
            expect(file1str).to.equal(file2str)  
         })
     })
    

    note: there looks to be a few other issues, one property has numbers with dashes in it, that’ll cause issues it should be string "phone": "123-456-7890". If thats coming from the API it needs fixing.

    without quotes javascript will assume this is a calculation not a static property so you’ll often end up in scenarios scratching your head at why you got the sum of the property subtracting the values instead of the complete phone number value.

    if your json is coming from an api it’s properties should always come in the same order, ensure that is the case in your test scenario too.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search