Gatling JSON Feeder Unique POST Bodies
Asked Answered
L

3

5

I have a JSON file that contains a JSON Array

test.json

[
  { "Name": "Bob" },
  { "Age": "37" },
  { "DOB": "12/01/1985"}
]

I would like to test each respective element in the JSON array against an endpoint to observe the performance of the system against unique payloads

currently I have

testService.scala

val payload = jsonFile("test.json").circular
val httpProtocol = http
    .baseURL("http://test.com")
    .headers(Map("Content-Type" -> "application/json"))

val scn = scenario("Test Service")
    .feed(payload)
    .exec(http("test_request")
        .post("/v1/test")
        .queryParam("key", "123")
        .body()

I am not able to pass each respective child from the payload in the .body() as a JSON

The Gatling Docs say that the JSON Feeder loads the each element of the Array into a record collection

https://gatling.io/docs/2.3/session/feeder/

i.e:

record1: Map("id" -> 19434, "foo" -> 1)
record2: Map("id" -> 19435, "foo" -> 2)

and set the body to .body(StringBody("""[{"id": ${id}}]"""))

The issue is I have different keys (Name,Age,DOB) and I'd like each one to be a different request sent.

.body(StringBody("""[{"KEY_NAME_HERE": ${KEY_NAME_HERE}}]"""))

How do I achieve this?

Littlest answered 5/9, 2018 at 14:27 Comment(0)
K
5

This is how i am doing:-

company_users.json.json

[
  {
    "env":"dev",
    "userName": "[email protected]",
    "password": "Qwerty!12345678"
  },
  {
    "env":"sit",
    "userName": "[email protected]",
    "password": "Qwerty!12345678"
  },
  {
    "env":"uat",
    "userName": "[email protected]",
    "password": "Qwerty!12345678"
  },
  {
    "env":"prod",
    "userName": "[email protected]",
    "password": "Qwerty!12345678"
  }
]

Working Code Snippet:

val jsonFileFeederCompany = jsonFile("data/company_users.json").circular

val get_company_user_token = http("Get Company Tokens")
.post(gwt_token_url)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body(StringBody(
  """{
      "env":  "${env}",
      "userName":  "${userName}",
      "password":  "${password}"
  }"""
)).asJson
.check(status.is(200))
.check(jsonPath("$.jwtToken").saveAs("jwtToken"))

val getCompanyUsersGwtToken = scenario("Create Company GWT token Scenario")
.feed(GetTokenRequest.jsonFileFeederCompany)
.exec(GetTokenRequest.get_company_user_token).exitHereIfFailed

This will read each array[position] from json and replace the values in request, to fetch security tokens from different env.

Hope this helps.

Regards, Vikram Pathania

Kristoferkristoffer answered 18/6, 2019 at 4:53 Comment(2)
incredible complicity :) what if I want to feed entire json to element from file here: body(StringBody not just build something with hands and string interpolation?Kashgar
IF u have 1K attributes what you are going to do?Bailor
G
1

In your case JSONs from that array are loaded one by one, and since each first level key from that JSON will be saved as session attribute then users in your simulation end up with just 1 of 3 attributes depending which JSON was used. This way you can't (or to be precise can't easily) build body string. In that simple case it would be better to have JSONs with same fields, so you can rely on them when building request payload. Fe. you can place payload key and value in separate fields:

[
  {
    "key":"Name",
    "value":"Bob"
  },
  {
    "key":"Age",
    "value":"37"
  },
  {
    "key":"DOB",
    "value":"12/01/1985"
  },
]

This way for each user in simulation you will have two attributes key and value so you will be able to construct payload like:

.body(StringBody("""{"${key}": "${value}"}"""))

Of course this will work only in that simple case you described and with string-only values in JSONs. If your final goal is to make something more complex please provide real-life example.

Goshawk answered 5/9, 2018 at 18:46 Comment(0)
P
0

This is how I did using Java 17, with Gatling 3.9:

Feeder File : searchFilters.json, the #{searchKey} is fed from a different csv feeder.

[
  {
    "filterType": "SUBJECTAREA",
    "pageSize": 10,
    "searchPhrase": "Im4mSearchFeeder"
  },
  {
    "filterType": "DELIVERYMETHOD",
    "pageSize": 10,
    "searchPhrase": "Im4mSearchFeeder"
  },
  {
    "filterType": "LOCATIONS",
    "pageSize": 10,
    "searchPhrase": "Im4mSearchFeeder"
  }
]

This is the java code that consumes the above json feeder :

public static ChainBuilder loadSearchItems() {
        FeederBuilder.FileBased<Object> searchFilterFeeder = jsonFile("/payload/courselaunch/searchFilters.json")
                .circular();
        return repeat(searchFilterFeeder.recordsCount()).on(
                feed(searchFilterFeeder).exec(searchItemsWithPreReqFilters("""
                        {"filterType":"#{filterType}",
                            "pageSize":#{pageSize},
                            "searchPhrase":"#{searchKey}"
                          }""")));
    }

    public static ChainBuilder searchItemsWithPreReqFilters(String elPayload) {
        return exec(
                http(transSearchItemsWithPreReqFilters)
                        .post(transSearchItemsWithPreReqFiltersEndPoint)
                        .headers(buildHeadersWithCustomizedInfo(SearchCatalog.class,
                                transCurrentUserLabelReferencesEndPoint,
                                currentUserPrefHeaders))
                        .body(StringBody(elPayload))
                        .check(status().is(200).saveAs("httpStatus")
                                , bodyString().saveAs("responsetransSearchItemsWithPreReqFilters")
                        ))
                .exec(session -> {
                    log.debug("Response Status: {}", session.getString("httpStatus"));
                    log.debug("responsetransSearchItemsWithPreReqFilters: {}",
                            session.getString("responsetransSearchItemsWithPreReqFilters"));
                    return session;
                });
    }
    
Plio answered 8/3 at 19:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.