JMeter – Working with JSON
The current project that i work for, was implemented to support JSON (JavaScript Object Notation) for its services. What is JSON, was my first question, and how will my WEB Testing behaviour change because of this?
Well, like most of the times, researching and old googling on the internet gave me the right answers to get me in a starting position. So let me just walk through the stepst that i have taken, in order to make my testplans send JSON payload together with my HTTP Post requests.
- So what is JSON?
JSON is simply a data format, but one which is more naturally fit for browser data consumption. The reason for this is that JSON is a subset to JavaScript, the de facto programming language used in all browsers. By structuring a data payload as a JSON response, you are effectively bypassing the need to parse an XML document in a browser — typically done via JavaScript of course — to get to the actual data.In this sense, JSON uses a stripped down syntax compliant with the native JavaScript interpreter provided on all browsers. Access and navigation to JSON data is done through the same standard JavaScript notation used to access string, array or hashtable values in a typical JavaScript application. Listing 1.1 illustrates what a JSON payload would look like.
Listing 1.1 : JSON payload example
{“item”: {
“description”: {
“title”: “Backroad Mountain Bikes”,
“name”: “Stump Jumper”,
“color”: “chrome”,
“image”: “/images/stumpjumper.jpg”,
“sizes”: “17,18,19″
},
“cost”: {
“salestax”: CA,
“rate”: 7,
“base”: 550,
“custompaint”: 150,
“warranty”: 50,
“travelcase”: 150
},
“instock”: “yes”
}}
This example was taken from an article published in 2006, under the following link:
JavaScript Object Notation for Ajax Web servicesOk, so basically JSON works with brackets, square and round paranthesis. It does indeed follow pretty much the JavaScript notation. And it misses the end tags in xml, which can (not sure about it yet) generate extra payload if xml is used (of course, there are some extra chars there…)
That being said, the only thing left was actually to integrate the JSON strings into my JMeter HTTP Request. - Send JSON Payload in HTTP Request using JMeter
Nothing simpler than this (yeah, right…now i’m saying it)…The only thing to do is to add the JSON Payload as Variable to be sent with the request (check it in the HTTP Sampler Properties for the HTTP Request that you are sending to the server).You do not need to name your variable. Sending the JSON Payload as value, for an empty variable should do the trick. Just make sure you copy the JSON Payload accordingly.
After posting the Request, you can analyze the result, by rendering the JSON Result, using JMeter’s integrated JSON Rendere (if you use the Result Tree, select your request, and go to the third tab, the one called “Response Data”, and from the bottom of the window, select “Render JSON”.
You thought it is going to be more than that? Nope, it’s that simple. And my next blog post will be about extracting values from a HTTP Request like that, returning a JSON String, and using it further in the Jmeter script as variables.
Enjoy,
Alex
Thanks for the run down, was useful. I had to also add HTTP Header Manager where I specified “Content-Type” to be overwritten by “application/json”. (per HTTP Request)
I’m looking forward to your next follow-up as this is my next task as well. I need to retrieve the Authentication Token to be used in further requests.
Hi Corical,
Can you please share how you did the 2nd part of your task? I’m looking for the same information. Apart from the Access_token I also have to save the Etags that are going to be generated in my test…
I would really be thankful for your reply.
Thanks
Hi drao,
what exactly is your problem? What are you trying to do?
Hi Suresh,
if the values are correctfully returned in your Debug Sampler, then the problem relies on how you pass the variable to your JSON string.
I usually do a dummy http request in order to see that my variables have been correctly replaced….something like:
http://localhost/${user}/${pass}
Can you post the JSON payload that you are sending in your request so we can check it out together?
Cheers,
Alex
Hi ALex,
Thanks for the response,
Below is some extra info about my testplan
My CSV config settings looks liek this-
FileName: C:\TestData\Dates_New.csv
Variables name: StartDate, EndDate
Delimiter: ,
Allow qouted data: False (i tried with setting this to true as well)
Json Payload is-
{“params”:[{"searchField":"Aberdeen","stayStartDate":"${StartDate}","stayEndDate":"${EndDate}","roomInfo":[{"noOfAdults":"2","noOfChildren":"0","disabilityRoom":false}],”searchSubType”:”0″,”searchType”:”5″}],”method”:”performSearch”,”id”:2}
And this is the response in debug sampler-
JMeterVariables:
EndDate=2010/06/18
JMeterThread.last_sample_ok=true
JMeterThread.pack=org.apache.jmeter.threads.SamplePackage@157b2d
START.HMS=172349
START.MS=1276532629718
START.YMD=20100614
StartDate=2010/06/17
TESTSTART.MS=1276532749500
Regards,
-Suresh
Hello Suresh,
i got it. I think i know what it is.
Do you have an extra space in your “csv configuration” config element? I mean, can you check that the two variables that you are using, are only separated by a comma, and not a comma and a space?
Cause by the looks of the output you gave me here, the EndDate variable has a space before it.
Check that the csv config element variables are declared like this:
StartDate,EndDate
and make sure that between the variables, there is only a comma.
Tell me if this was the case.
Regards
Hello Alex,
Yes, there was a space between variables in ‘CSV Data Set Config’. Removing that space worked for me
Many thanks Alex.
Regards,
-Suresh
Hi Alexandru Ersenie
It would be great , if there were sample Jemter Test Plans with the , it would be a great help to get started and explore
Thanks,
Ajay
Hello Alexandru Ersenie,
It would be helpful if you can post the Test Plan with the blog post , so it would be easy to start with
Thanks,
Ajay K
Hi Alex,
Could you please explain me , how to parameterize the data in JSON apis.
Hi Sankar,
can you be a little bit more specific please?
Hi Alex,
Thanks for your quick response..
my JSON api has some values, which I need test with different values for the same api..
Consider below api for example..
{“params”:[{"searchField":"Aberdeen","stayStartDate":"${StartDate}","stayEndDate":"${EndDate}","roomInfo":[{"noOfAdults":"2","noOfChildren":"0","disabilityRoom":false}],”searchSubType”:”0″,”searchType”:”5″}],”method”:”performSearch”,”id”:2}
I want to parameterize “noOfAdults”, “noOfChildren” and “searchType” with different values for the above api.
Please explain me in details as I am new to this type of testing..
I am trying to avoid re-writing the same api with different values.
is there any way to do like data driven testing in QTP?
Please let me know.
Here is my JSON payload, tried with CSV data set config..but no luck. I am trying with different values for countrycode and languagecode..Please let me know if you are able to replace different values with this payload.
{
“payload”: [
{
"version": 1,
"sequenceId": 1,
"message": {
"class": "xxxx.xx.xxxx",
"uniqueIdentifier": "050c8e4475fe9648f6bc20ce1729d973f090c6a3",
"platformCode": "test",
"deviceName": "test",
"hardwareVersion": "1.0",
"platformVersion": "0.1",
"countryCode": "us",
"languageCode": "en"
}
}
]
}
Hi Sankar,
are you trying to extract or to pass the countrycode and language code?
If trying to extract that from a response, you need to do that by adding a regular expression extractor, with the following regular expression:
“countryCode”: “(.+?)”
This will extract only the code, like “us” or “uk” or whateve.
If you are trying to post, than i guess there is nothing simpler as a variable, case which your payload would lokk like:
“countryCode”: “${country_code}”
where of course country_code is your predefined variable.
I am afraid i did not quite get what you are looking for.
Let me know,
Alex
Hi Alex,
I am trying to post the different values, I tried with the payload as “countryCode”: “${country_code}”, defining CSV variables but it is not picking values instead it is writing ${country_code} in database, not sure what to do..
I am trying to post the different values, I tried with the payload as “countryCode”: “${country_code}”, defining CSV variables but it is not picking values instead it is writing ${country_code} in database, not sure what to do..
First of all, watch out how you define your csv file. If you do not provide the full path to the file, jmeter will consider the file to be located in the same folder where the testplan is. I suggest building a csv folder structure, and provide the full path to the csv.
Secondly, the csv file has to be under the main thread group. Otherwise no thread will parse it, hence the values will not be read.
Third, if the country_code is the first column in your csv file, than the first csv variable should be country_code.
Your problem is not the post, but reading from csv file. It is a little bit tricky, but with a little bit of effort and help, you’ll get it running.
it is is not using GET or POST methods, instead it is using PUT, where the path and URL does not have any variables in it..
hi,
i am facing a problem with parameters in jmeter… i have a few query string values to be passed to a service along with a json input. I am specifying json via file and request paramteres in jmeter’s “Send parameter with request” section but jmeter is treating my request parameters as json an gives an exception that it expects ‘{‘ at start of json and points the location of exception to my request parameters. i need to know how to specify both request parameters and json input
Hi Alexandru,
Here is my case: I’m trying to use Jmeter to test some RESTApis.
I have managed to get the access_token etc by creating separate test plans and hard coding the Access_token that I got from my 1st POST request. etc…
Now I want to tie all the POST and GET case that I have in one test plan for either doing Regression/Load when ever there is a need.
1) POST: I have to send a HTTP POST request to by sending information in the header.
So have used HTTP-Header Manage and have added:
Accept-Version ~1
Content-Type: application/json
Authorization: Basic (uses base64 encoding)
Then have a Http-Request Sampler and added the following body
{
“grant_type” : “password”,
“username” : “usernameid”,
“password” : “passwordkey”
}
I get the following response: “access_token”:”xxxxxxx”,”token_type”:”Bearer”,”expires_in”:86400}
Now I’ve to use this access_token as it is dynamically generated all the time into my next test case which is going to be GET and in that get I’ve to again pass values into the Http-Header
Authorization: Bearer
So far I’ve gotten to a point where I’m using Regular expansion extractor and using
Ref name:access_token
Reg Expression: {“access_token”:”(.+?)”
Template: $1$
Match No. 1
Default:
and then created added Http-Header to the main Test-plan it self
and am now trying to pass Authorization : Bearer ${acces_token} [from the above regular expression extractor and hoping that the variable is read]
My problem is that the header with Authorization is not sent… and as a result i get 401…and it asks me “who are you”
I’m sorry if this above post looks long and childish. I am sorry
i badly need help on this and I have been stuck for days now
( I’m new to this so please any help will be appriciated and will be grateful for it.
Thanks
Just to add I have managed to to pass the variables but i am getting 401.
I look at my http request and am seeing that my Authorization is correct i.e. bearer
but am seeing content-type : application/json also being sent in my request.. not sure why this is getting added!!! any idea?
I’m thinking it might be from the 1st test case where am sending this in the header. can you plz tell me how to fix this problem?
Hello,
I have been reading your blogs for json with Jmeter and they are VERY useful especially regular expression extractions.
Now i am facing a strange behavior in paramterization of date values in json request. There are two date values(startDate and EndDate). I am using a comma seperated CSV file for my testdata. The value passed from this CSV file to EndDate is not getting replaced whereas the value for StartDate is sucessfully getting repalced. Both the values has been passed from the same CSV file.
I have CSV config configured properly and i can see in Debug Sampler and the values for StartDate and EndDate from CSV were read sucessfully.
Please explain solution for this behavior.