k1LoW / runn

runn is a package/tool for running operations following a scenario.
https://runn.run
MIT License
403 stars 30 forks source link

How can I load multiple JSON files as an array? #977

Closed karrybit closed 3 weeks ago

karrybit commented 3 weeks ago

We are considering adopting runn as our API test tool. In our testing, we aim to keep the runbook simple and manage variations through input data. However, it does not work as expected when loading multiple JSON files into the vars array variable in runn.

desc: normal case
debug: true
runners:
  api: http://localhost:8080
vars:
  data:
    - json://data/hoge.json
    - json://data/fuga.json
    - json://data/piyo.json
steps:
  request:
    loop: len(vars.data)
    api:
      /:
        post:
          body:
            application/json: "{{ vars.data[i] }}"
    test: current.res.status == 200

In this case, instead of expanding the JSON's contents, it sends the string "json://data/hoge.json" as the request.

❯ runn --version
runn version 0.113.2
❯ go run main.go # terminal A

❯ runn run runn/normal.yaml  # terminal B
Run "api" on "normal case".steps.request
-----START HTTP REQUEST-----
POST / HTTP/1.1
Host: localhost:8080
Content-Type: application/json

"json://data/hoge.json"
-----END HTTP REQUEST-----
-----START HTTP RESPONSE-----
HTTP/1.1 400 Bad Request
Content-Length: 0
Date: Tue, 25 Jun 2024 06:14:03 GMT

-----END HTTP RESPONSE-----
Run "test" on "normal case".steps.request.loop[0]
F

1) runn/normal.yaml da3f408100164af52116225166e69c50f5a31707
  Failure/Error: loop failed: test failed on "normal case".steps.request.loop[0]: condition is not true

  Condition:
    current.res.status == 200
    │
    ├── current.res.status => 400
    └── 200

  Failure step (runn/normal.yaml):
  12     loop: len(vars.data)
  13     api:
  14       /:
  15         post:
  16           body:
  17             application/json: "{{ vars.data[i] }}"
  18     test: current.res.status == 200

1 scenario, 0 skipped, 1 failure

I have also tried the following, but the result was the same.

desc: normal case
debug: true
runners:
  api: http://localhost:8080
vars:
  data:
    - "{{ json://data/hoge.json }}"
    - "{{ json://data/fuga.json }}"
    - "{{ json://data/piyo.json }}"
steps:
  request:
    loop: len(vars.data)
    api:
      /:
        post:
          body:
            application/json: "{{ vars.data[i] }}"
    test: current.res.status == 200

Is there a way to load multiple JSON files at once? Here is the reproducible code.

Thanks.

k1LoW commented 3 weeks ago

@karrybit Thank you for your question.

json:// or yaml:// is currently only available at the first level of vars/params.

It is possible to use wildcards instead.

$ cat normal.yaml
desc: normal case
debug: true
runners:
  api: http://localhost:8080
vars:
  data: 'json://data/*.json'
steps:
  request:
    loop: len(vars.data)
    dump: vars.data[i]
$ runn run normal.yaml
Run "dump" on "normal case".steps.request.loop[0]
{
  "bar": 2,
  "foo": "fuga"
}
Run "dump" on "normal case".steps.request.loop[1]
{
  "bar": 1,
  "foo": "hoge"
}
Run "dump" on "normal case".steps.request.loop[2]
{
  "bar": 3,
  "foo": "piyo"
}
.

1 scenario, 0 skipped, 0 failures
$
karrybit commented 3 weeks ago

Thank you for your response.

I plan to prepare and execute a test data set that violates variations to test API validation. With your solution, I can meet my requirements by unifying the file names or creating a directory to consolidate the test data.