Verifying the Identity of JSON Texts

Verifying the Identity of JSON Texts

Test data might not always be present in the form of line-based file formats, like Comma-separated Values or Tab-separated Values. The JavaScript Object Notation (JSON) format — a lightweight subset of the JavaScript language — gained a lot of popularity as an exchange format when communicating with Web Services in the past years. The application to be tested might offer an export functionality that allows the export to be in JSON format, and we are supposed to verify the exported file is correct. In addition, the exported file is not required to match the expectation character-by-character. So object keys are not required to show up in a given order, and there are also no constraints to whitespace usage. This flexibility makes it hard to come up with a simple solution when it is about to compare two JSON texts.

Example Usage with Squish

Luckily, Squish provides the test.compareJSONFiles(expectedFile, actualFile) function that takes care of that flexibility while comparing two JSON files.

For this example, we will use Python as the scripting language, but the function is available in all other scripting languages Squish supports as well.

Let’s test drive the test.compareJSONFiles() function using one of the various JSON formatting webservices. The test case is defined easily: we inject a JSON text, and – after pressing a button – expect the reformatted JSON text to be equal to the given one.

We create a new test suite and test case, and a test data file ‘input.json’ that holds a sample input JSON text:

[1,
2,
{"success": false, "error":
31},
3]

And we add a test script like this:

# -*- coding: utf-8 -*-

import names

def main():
    startBrowser("https://jsonformatter.curiousconcept.com/")

    with open("testdata/input.json", "r") as inp:
        inputData = inp.read()

    typeText(waitForObject(names.formatter_input_area), inputData)

    selectOption(waitForObject(names.formatter_options_select), "Compact")
    clickButton(waitForObject(names.formatter_process_button))
    formatted = waitForObject(names.formatter_result_area).innerText

    with open("/tmp/actual.json", "w") as out:
        out.write(formatted)

    test.compareJSONFiles("testdata/input.json", "/tmp/actual.json")
    test.compareTextFiles("testdata/input.json", "/tmp/actual.json")

We start a new browser with the given URL (line 6). We read the JSON text we want to pass to the web service from our test data file (8). We type that text into the corresponding input area (11), choose a different formatting option to make the formatting web service actually do some changes to our input data (13) and pick up the re-formatted JSON text from the result area (15). To comply with the test.compareJSONFiles() API (it takes paths to files in the filesystem), we write the retrieved JSON text to disk (17).

Finally we compare our two files. This is the relevant part in the test results:

<scriptedVerificationResult time="2019-07-11T14:45:36+02:00" type="PASS">
...
    <text>JSON Comparison</text>
    <detail>Files are equal</detail>
</scriptedVerificationResult>

As confirmation how different the files are on a character-by-character level, we check what test.compareTextFiles() reports:

<scriptedVerificationResult time="2019-07-11T14:45:36+02:00" type="FAIL">
...
    <text>Plain Text Comparison</text>
    <detail>'input.json' and 'actual.json' are different. Diff:
-   [1,
- 2,
- {"success": false, "error":
- 31},
- 3]
+ [1,2,{"success":false,"error":31},3]</detail>
</scriptedVerificationResult>

So while the latter function shows how both JSON files differ textually, compareJSONFiles() allows us to determine that both JSON texts in fact equal each other.

0 Comments

Leave a reply

电子邮件地址不会被公开。 必填项已用*标注

*