bp3
bp3

Reputation: 245

How to use fully functional JsonPath in RobotFramework?

Could you please recommend how to use JsonPath in the Robot Framework? It should supports multi-level query as following:

$.items[?(@.status.name="closed")].name

I'm seeking the way to make following work:

*** Variables ***
${json}         {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${json_path}    $.items[?(@.status.name="closed")].name
*** Test Cases ***
Get closed item
    ${names}=    Get Json Items    ${json}    ${json_path}
    Should be equal    ${names[0]}    item2

someting like this

Upvotes: 1

Views: 5275

Answers (1)

Jan Kovařík
Jan Kovařík

Reputation: 1582

This RF code does what you need but ONLY for provided json structure. From my point of view you should play with Get Json Value and prepare keywords you need. BTW, it is obvious that such json/string handling in RF is a bit complicated so I would rather write small Python library with keywords you need.

*** Settings ***
Library            Collections
Library            HttpLibrary.HTTP

*** Variables ***
${json}         {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${name}    ${EMPTY}
${result}    ${EMPTY}

*** Test Cases ***
Get Closed Item
    ${name}    Get Name By Status    ${json}    closed
    Should Be Equal As Strings    ${name}    item2
    ${name}    Get Name By Status    ${json}    opened
    Should Be Equal As Strings    ${name}    item1

*** Keywords ***
Get Name By Status
    [Arguments]    ${json}    ${status}
    [Return]    ${result}
    ${json}    Parse Json    ${json}
    :FOR    ${item}    IN    @{json["items"]}
    \    ${item}    Stringify Json    ${item}
    \    ${name}    Get Json Value    ${item}    /name
    \    ${name}    Parse Json    ${name}
    \    ${status_name}    Get Json Value    ${item}    /status/name
    \    ${status_name}    Parse Json    ${status_name}
    \    ${result}    Set Variable If    '${status_name}' == '${status}'    ${name}    ${result}

Edit: based on comment below I would go for such python based code.

JsonpathLibrary.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
import jsonpath

class JsonpathLibrary(object):

    def get_items_by_path(self, json_string, json_path):
        json_object = json.loads(json_string)
        match_object = jsonpath.jsonpath(json_object, json_path)
        match_string = json.dumps(match_object[0])
        return match_string

RF code:

*** Settings ***
Library            JsonpathLibrary.py

*** Variables ***
${json}         {"items":[{"name":"item1","status":{"id":1,"name":"opened"}},{"name":"item2","status":{"id":2,"name":"closed"}}]}
${json_path}    $.items[?(@.status.name=="closed")].name

*** Test Cases ***
Some Descriptive Name Here
    ${name}    Get Items By Path    ${json}    ${json_path}
    Should Be Equal As Strings    ${name}    "item2"

Upvotes: 1

Related Questions