Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Leveraging JsonPath for Precise JSON Validation in Automated API Testing

Tech 1

What is JsonPath?

JsonPath is a lightweight query language for JSON that lets you pinpoint and extract any fragment from a document with a single expression. Available in Java, Python, JavaScript, PHP, and more, it behaves like XPath for XML and is indispensable when you need to assert values, lengths, or structure inside large JSON payloads.

Root reference: $ denotes the entire document.

Core Syntax

Operator Meaning
$ Root object
. or [] Child navigation
* Wildcard for all elements
.. Recursive descent
[n] Array index (zero-based)
[?(@.key op value)] Filter epxression
@ Current node

Examples:

$.shop.items[0].name
$['shop']['items'][0]['name']
$..items[?(@.price > 100)].id

Quick-start in Python

Install:

pip install jsonpath-ng

Sample payload:

payload = {
  "shop": {
    "items": [
      {"id": 1, "name": "Espresso",  "price": 129},
      {"id": 2, "name": "Cappuccino", "price": 109},
      {"id": 3, "name": "Latte",     "price": 99,  "isbn": "0-110-234567-30"},
      {"id": 4, "name": "Mocha",     "price": 89,  "isbn": "0-13095-19295-8"}
    ],
    "meta": {"color": "red", "discount": 0.1}
  }
}

1. Collect all item names

from jsonpath_ng import parse
expr = parse('$.shop.items[*].name')
names = [match.value for match in expr.find(payload)]
# ['Espresso', 'Cappuccino', 'Latte', 'Mocha']

2. Fetch every object that owns an ISBN

expr = parse('$.shop.items[?(@.isbn)]')
items_with_isbn = [match.value for match in expr.find(payload)]
# [{'id': 3, ...}, {'id': 4, ...}]

3. Slice the first two items

expr = parse('$.shop.items[:2]')
first_two = [match.value for match in expr.find(payload)]

4. Grab the last element

expr = parse('$.shop.items[-1:]')
last_item = [match.value for match in expr.find(payload)]

5. Filter by numeric condition

expr = parse('$.shop.items[?(@.price > 100)]')
expensive = [match.value for match in expr.find(payload)]
# [{'id': 1, ...}, {'id': 2, ...}]

6. Nested filter with multiple criteria

expr = parse('$.shop.items[?(@.price > 90 & @.isbn)]')
filtered = [match.value for match in expr.find(payload)]
# [{'id': 3, ...}]

Tips for Test Suites

  • Store reusable expressions in a map to keep assertions DRY:
selectors = {
    'all_prices': '$.shop.items[*].price',
    'max_price':  'max($.shop.items[*].price)',
    'has_isbn':   '$.shop.items[?(@.isbn)]'
}
  • Combine JsonPath with pytest-check or assertpy for fluent asertions:
from assertpy import assert_that
prices = [match.value for match in parse(selectors['all_prices']).find(payload)]
assert_that(prices).is_not_empty().contains(129)
  • Use online playgrounds such as jsonpath.com to prototype expressions before committing them to code.

Common Pitfalls

  • Indexes start at 0 in JsonPath, unlike XPath (1-based).
  • Empty results return False in some libraries—always check length or truthiness.
  • Escaping special characters in keys: $['item-with-dash'].

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.