hurl icon indicating copy to clipboard operation
hurl copied to clipboard

Documentation of Hurl testing with `nth-filter`.

Open nopeNoshishi opened this issue 10 months ago • 2 comments

I am one user who has always used Hurl! This tool is very useful for external testing and is also very useful in my team.

Proposal

Even if the JSONPath results are returned as an array, scalar comparisons can be simplified by using Hurl's nth filter. Adding this as an example in the documentation would help many users solve similar issues smoothly.

Background/issues

When using JSONPath in Hurl, even unique elements are retrieved as arrays, so comparisons such as == ‘value’ can be difficult to use as is. Also, if you try to write == [value] directly on an array, errors such as invalid predicate value may occur, making the test confusing in some cases.

Example: structure of JSON

{
  "items": [
    {
      "category": "fruit",
      "info": {
        "code": "APPLE001"
      }
    },
    {
      "category": "vegetable",
      "info": {
        "code": null
      }
    }
  ]
}
  • category == ‘fruit and its info.code is "APPLE001".
  • category == vegetable and its info.code is null

In such a structure, the filter [? (@.category == ‘fruit’)]] will give ["APPLE001"] as an array, which is difficult to compare directly with the scalar "APPLE001".

In practice, the following cases fail.

# Cannot specify an array on the right-hand side
jsonpath "$.items[?(@.category == 'fruit')].info.code" == ["APPLE001"] # NG

# Cannot access index even though it is an array
jsonpath "$.items[?(@.category == 'fruit')][0].info.code" == "APPLE001" # NG

Solution using the nth-filter

An nth filter exists in Hurl that takes out elements of an array as scalars, and can be used to compare them succinctly and reliably by writing

jsonpath "$.items[?(@.category == 'fruit')].info.code" nth 0 == "APPLE001" # OK
jsonpath "$.items[?(@.category == 'vegetable')].info.code" nth 0 == null.    # OK

If you like, please consider adding the above to the documentation as an example of ‘Scalar comparison when the JSONPath result is an array’. It would be very helpful to have this in the official documentation, as it is a point where users can easily get tripped up.

I feel that the information is in a distant place because it was not solved by actually getting an answer from the generated AI etc. and I understood it while reading the actual source code and looking for the test sample.

Thank you!

nopeNoshishi avatar Mar 19 '25 08:03 nopeNoshishi

Hi @nopeNoshishi thanks for your issue, we'll try to improve the documentation!

jcamiel avatar Mar 19 '25 08:03 jcamiel

Indexing after a filter (e.g. $.items[?(@.category == 'fruit')][0]) is desparately needed. Dealing with nth 0 is really awkward as you always need to think in terms of arrays, and certain filters like exists/not exists don't compose with nth 0, so you need to use isEmpty which is not really equivalent to not exists.

simonzkl avatar Apr 07 '25 10:04 simonzkl