artilleryio / artillery

The complete load testing platform. Everything you need for production-grade load tests. Serverless & distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.js module.
https://www.artillery.io
Mozilla Public License 2.0
8.06k stars 512 forks source link

JSONPath flattened array results in a random value being selected. #853

Open Plitzer opened 4 years ago

Plitzer commented 4 years ago

When capturing a flattened JSONPath array (e.g. using the * selector) the resulting variable contains one value selected at random from the array.

This should be storing the whole array into the variable.

EDIT: I have noticed that this is being intentionally done in the code to simplify the syntax. I don't think it is good practice to support JSONPath and then alter the expected return values. If a user wants an id from a single object (e.g. $.id), then using JSONPath they should know to use $.id[0] Instead, you have provided a small amount of sugar while breaking other JSONPath functionality.

This will be a pretty major breaking change, but the implementation should be returning the results directly from the query.

Minimal repro:

config:
  target: 'https://jsonplaceholder.typicode.com'
  phases:
    - duration: 5
      arrivalRate: 1
scenarios:
  - flow:
    - get:
        url: "/todos"
        capture: 
          json: "$[*].id"
          as: "todoIDs"
    - log: "todoIDs: {{ todoIDs }}"
RandScullard commented 3 years ago

I think this is an excellent suggestion.

In my scenario, I want to have each virtual user get a JSON list of the document IDs assigned to them, then loop through the IDs and perform an operation on each one. This would be trivial using capture and the loop-over construct if I could just capture the IDs into an array variable, as @Plitzer describes above. I know I can do this with custom JavaScript, but it seems like a great fit for Artillery to provide this natively.

This would be fully backward-compatible if the script could specify an array: true attribute under the capture to get this new array behavior, for example:

    capture: 
      json: "$[*].id"
      as: "todoIDs"
      array: true
leduyminh48 commented 3 years ago

yes, it is frustrating to find out since the documentation makes it look like it fully supports syntax of json path

organom commented 2 years ago

any update on this? Documentation is very lacking and misleading