Overview:
There are so many ways and tools available to test a REST API.
When I had a requirement to test a REST API, after looking at various tools & options, I settled on JMeter for the following reasons.
- JMeter is FREE & Open Source.
- JMeter can read your testdata from the CSV file out of the box. Parameterization is very easy.
- API can be tested with multiple sets of data easily.
- JMeter has a powerful ‘Response Extractor‘ s – which can be used to extract information from the API response (JSON / XML / Regular expression) and use it in the subsequent requests in the test.
- JMeter has tons of ‘Assertions‘ – to verify the if the API response is as expected.
- The JMeter test we created for functional testing can also be used for performance testing.
- ANT / Maven / Gradle plug-ins to execute the test as part of your build.
- Easy integration with Jenkins to run the test periodically & Jenkins has a plugin for JMeter to parse the result file & display nice charts.
Installing JMeter:
If you do not have JMeter installed in your machine, check this link. It has detailed steps to install JMeter.
Once you launch JMeter, You will see Test Plan element which is the root node of the JMeter test under which we will add various JMeter elements for our test.
Create a Simple API JMeter Test:
Now Lets add the required elements for our test.
- Add a Thread Group under the test plan. (Rightclick on Test Plan –> Add –> Threads (users) –> Thread Group)
- We update the number of users, number of iterations etc in the Thread Group.
- Let them be 1 for now.
- Add a HTTP Request Sampler under the Thread Group. (Rightclick on Thread Group –> Add –> Sampler –>HTTP Request)
- Sampler is a type of JMeter request.
- REST is an approach & it uses HTTP protocol. So we add the HTTP Request sampler.
- Update Server IP / Hostname as myapiservername.com [For this API url : http://myapiservername.com/rest/api/path]
- Update the API path /rest/api/path
- Send Files with the Request – should have the path of your request JSON file OR include the request JSON in the Body Data section of the HTTP Request.
- Add a HTTP Header Manager (Rightclick on Test Plan –> Add –> Config element –> HTTP Header Manager)
- In HTTP Header Manner config page, click on ‘Add’.
- Include this name-value pair.
- Name=Content-Type
- Value=application/json
- If your API expects APIGEE key, then include it here or ignore.
- Name=apigeekey
- Value=test@123
- Add a HTTP Authorization Manager – Required in case of any authentication. (Rightclick on Test Plan –> Add –> Config element –> HTTP Authorization Manager)
- Update the Base URL as http://myapiservername.com
- Update the username
- Update the password
- Under Test Plan, add a listener – View Results Tree
Your JMeter test will look like this (I did not include the listener).
Now if you run this, you should be able to send the request and get the response successfully.
Note: If it does not work for some reason, try changing the HTTP Request Implementation to Java/Other values and give a try.
Whatever we have done so far is a very simple test – like a POC. Now lets see how it can be improved further.
Parameterizing the test data:
In the above example, we send the hard coded request JSON to test the API. We might have to test the API for different sets of data.
Lets take a very simple example, I have an API which gives the book name and price details for the book id request i send.
Testdata in CSV:
Request JSON:
Lets assume that our API request in the below format.
{
"bookid": 1
}
Response JSON:
Lets assume our API response is as given below.
{
"bookname": "Awesome Jmeter"
"bookprice": 23.5
}
Add CSV Data Set Config under Test Plan & update the details as given above.
- Variable Names : can be blank. JMeter will take the CSV column names as variable names.
- Recycle on EOF? : should be FALSE. We are going to test each row only once.
- Stop Thread on EOF? : should be TRUE. It will stop the JMeter test automatically once we tested for all the rows.
- In Thread Group, select the ‘For Ever’ check box in the Loop Count.
Parameterize:
Instead of sending the hard coded book id, lets parameterize it by using the value from the ‘id’ column of the CSV file.
That’s it. If you run the test now, it should send 6 requests one by one for each row in the CSV file.
We can do a lot better than this – what if there are different types of request – GET / POST / DELETE / PUT / PATCH etc. It is super easy with JMeter. I drive my tests completely through a spreadsheet as shown here. Please check here for the advanced usage of JMeter – REST API – Data-Driven testing
Assertion:
If we can send the request and get the response, are we done? Nope!! But, We are almost there!!
We need to validate if we get the expected response. So, one last step would be to add the assertion.
I have the expected book name and price details in the CSV file shown in the above example. Lets use those details to check if our API works as expected.
Add Response Assertion under HTTP Request as given below. We need to verify if we have the expected book name and price in the response. Add them as given below.
This assertion will validate the response and Pass/Fail the test accordingly. (Ensure that Pattern Matching Rules is ‘Contains’ as we are checking only for the book name and price. We are not verifying the whole response.)
Duration Assertion:
JMeter not only verifies text – but also the ‘time‘ the request took. If we add ‘Duration Assertion’ and set an acceptable time limit, JMeter can confirm if the response was received within the time limit.
Extracting Data From JSON Response:
Sometimes you might want to extract specific data from JSON response and pass this data to the subsequent request in JMeter. JMeter provides a JSON Extractor to extract particular value from the JSON response.
Lets assume, my sample response looks like this.
{
"title":"In Search of Lost Time",
"author":"Marcel Proust",
"id":1
}
I could add a JSON Extractor as shown below to extract the value of the author into the variable authorValue.
- $ refers to the root element in the JSON Path expressions
- ‘author’ is immediate child of the root element. So it can be accessed using $.author
- Match Number gives the Nth match. If you want all the matching value in an array, Match Numbers should be -1
- Default Values – used when there is no match
Lets consider below JSON response
{
"store":{
"book":[
{
"category":"reference",
"author":"Nigel Rees",
"title":"Sayings of the Century",
"price":8.95
},
{
"category":"fiction",
"author":"Evelyn Waugh",
"title":"Sword of Honour",
"price":12.99
}
],
"bicycle":{
"color":"red",
"price":19.95
}
}
}
- To get the first book price – $.store.book[1].price
- To get all prices from category – $..price
More information on this can be found here.
Performance Testing on REST API:
You might have verified the API functionality!
But, How do we know that about the following information on the API?
- Response time it takes
- Concurrent users it can support
- User load at which it breaks
- CPU/Memory usage
- Memory leak
JMeter can help here as well by using the same test we had just created!!
- Update the Number of thread in the Thread Group. If you enter 10 as number of users & run, JMeter will simulate 10 concurrent users.
- Update the Ramp up period (in seconds). For ex: If you have 10 users & 50 seconds as Ramp up period, JMeter will start creating 1 virtual user for every 5 seconds.
- Loop count: Select ‘Forever’.
- Under Scheduler, enter Duration in seconds. [Entering 600 will run the performance test for 10 mins with 10 Virtual Users.]
- Update CSV Data Set Config : ‘Recycle on EOF?’ – set it to TRUE – [FALSE will read the CSV data only once. We need enough data for VUsers to run for 10 mins. So setting it to TRUE will feed the same set of test data once it is read]
- Add a ‘Aggregate Report’ listener under the Test Plan.
Run your Meter test now. ‘Aggregate Report’ will give a basic idea of your REST API performance metrics like number of requests made in given duration, average response time, throughput, ‘90% line’ etc. [Note: It is not a good practice to run JMeter performance test in GUI mode as we just did now as it consumes more memory. Please check this Tips & Tricks for the best practices to be followed.]
Summary:
We just have created a Simple Data Driven Framework to test the functional behavior of REST API using JMeter without using any programming language. We also saw how to do performance testing on our API using JMeter by reusing the same script created for functional testing.
You might want to continue reading more about for the advanced usage of JMeter – REST API – Data-Driven testing
Are you new to JMeter? – Then you should totally check this article out which gives more information on the JMeter best practices and common mistakes beginners make.
Happy Testing & Subscribe 🙂
I followed the method to test my rest API service but I am getting a 415 error code unsupported media type error message.
I am using VPN to connect to the application. It is a POST method
Hi Anand,
Server will return 415 error code when it is not able to process the content-type of the request. So I assume you have set it to application/json.
Does your request body have any json?
Yes my request has Json. Also I have set the Content Type to application/json. But I get the issue still
Try to change the content-type to application/json; charset=utf-8 & try.
If it still does not resolve the issue, Is it possible for me to have a look at the request?
Also – Please try with this chrome extn – https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=en-US.
just to ensure if it is not specific to JMeter.
Hi,
I may not be able to provide the actual request but will provide the details of my request
HTTP Request Sampler:
Host name: ; Port: 8080
Implementation Java; Protocol: HTTP; Method POST; Content encoding; UTF-8
Path: /rest/user/register// user id is any random number and access token is passed as NULL so that the system identifies it as a System Admin user registering to the service
Follow redirects: Checked; Use Redirects: Checked
Raw POST Body : {“name”:”adminNew”,”userCategory”:”SYSTEM_ADMIN”,”companyCode”:”DEFAULT_COMPANY_CODE”}
Http Header Manager
Content-Type: application/json
I was just wondering whether this could be something related to Json lite not recognized by the server. Kindly put in your thoughts for the same.
Also tried with Advanced Rest Client Application with Chrome, but here as well I am getting error code 415.
But the request is working fine with Postman client
I am resending the requests in my previous comment which has not appeared
Path: /rest/user/register/userid/accesstoken where user id is any random number and access token is passed as NULL so that the system identifies it as a System Admin user registering to the service
As you confirmed that you 415 error even with Chrome extn, the issue does not seem to be specific to JMeter.
Your setup looks good to me. Lets try these!
If it is still does not help, Can you see how the request is being sent by the Postman client – using JMeter proxy server? If we can record, then we will know what is missing in the request we send through JMeter.
Hi,
My script started to work as the dev team confirmed that they are serializing the json to string at client side and desterilize it at server. So i gave text/plain as content-tpe and it started working. Thank you for all the help in understanding things.
I have a new problem, I am using Response Assertion to validate my response against csv. But I would also like to enter the status of each request in the csv against each row. Will I be able to use Bean Shell assertion here if so how? Kindly explain
Thanks
Anand
Response Assertion can also compare the response code.
But, We will have more control over Beanshell Assertion.
To check the HTTP response code (assuming you have stored the expected response code in CSV in ‘resCode’ column),
if (ResponseCode.equals(vars.get("resCode")) == true && ResponseData.contains(vars.get("expectedMessage")) == true ) {
SampleResult.setResponseOK();
}else{
Failure=true;
FailureMessage="Response code/data not as expected";
}
Thank you for the response, this works. I tried adding a BeanShell listner to the plan which actually writes the error code from the response. But the write file loops infinitly, i.e the values are entered endlessly in the csv. Below is my code
refnum = vars.get(“Error Count”);
f = new FileOutputStream(“D:/Apache Jmeter 2.11/apache-jmeter-2.11/Input_Admin.csv”, true);
p = new PrintStream(f);
this.interpreter.setOut(p);
print(“Error Count,” + refnum);
f.close();
Could you please help
also would like to know if I need to write the results into a particular cell say Column D Row 1 to 9 from jmeter will that be possible??
Thank you very much! Its a great help 🙂
Glad that it was helpful. 🙂
When we use the CSV file for Post Request than we need to change the content-type from application/json to text/csv ? if yes then if you services only allow json request then you can advise the solution?
Aim of this article is to test a REST API usinh JMeter. For that the content-type should be application/json only.
Uploading some CSV files using HTTP requests ca also be done using JMeter. You can simply record your actions on Browser using JMeter.
I will check this link for more details – https://jmeter.apache.org/usermanual/jmeter_proxy_step_by_step.pdf
Thanks for the article. Is there a way we can use this with CI (Continuous Integration) tools like Jenkins?
Yes, If we can run a program/application using commandline, we can integrate it with Jenkins as well.
I using protocol https with 3 headers to test API. My test succeed in post man but i have response code 401 ( unauthorized ) when setting up and running in jmeter. I’m using same value for header parameter in postman and jmeter.
Please help me! Thanks so much!
I would advise you to post your issue with more details in StackOverFlow (http://stackoverflow.com/questions/tagged/jmeter).
Someone will help you. But please make sure you give all the information.
Hi,
I was trying to make a script to test REST services using Jmeter.
Till now I was using Chrome’s Advanced REST Client.
My authentication request was GET and it was something like this in Advanced REST:
https://username:password@URL:portnumber
its a GET request
Now when I am using Jmeter. I tried following ways:
I added HTTP Authorization Manager and mentioned Base URL and Username/password inside it.
When I am trying to do a request then its showing me “Unauthorized”
I also tried to login using normal https request but no success.
When accessed manually, a authorization popup window appears and username and password is submitted inside this window.
Please suggest me a way for how to login using Jmeter.
Can you raise this question in StackOverFlow.com with more details, please?
why i am i getting fail in my reports for the assertion to check name and price.
More details plz!!
Thank you . This article gives me a clear idea. But let me know how can I find out
a. CPU usage
b. Memory Leak.
Thnaks.
http://www.testautomationguru.com/jmeter-server-performance-metrics-collector/
Thanks for the post, Could you please write an article on how to compare two xml responses and print the output which are not identical – this is for functional tests. Thankyou beforehand for help.
I am having problem like – my rest api will give result if we give access token or else it give 401 error. How to pass where to pass access token in jmeter.
You would be sending the info in ‘HTTP Authorization Manager’
Query: I want to extract large data from Response Data of Request#1 and apply to BodyData of Request#2 as well as need to parameterize few values. Is it possible from Jmeter GUI? If Yes, please help.
Yes. You need to use Regular Expression Extractor. Check this site – http://eclipsesource.com/blogs/2014/06/12/parsing-json-responses-with-jmeter/
How to perform performance testing of REST api if we use PDF or Text files as input for Post Request?
JMeter can upload/download files as well. Check this site. https://www.blazemeter.com/blog/how-performance-test-upload-and-download-scenarios-apache-jmeter
I want to test an Rest API service, How many users i can apply by using J meter tool
Very difficult to answer as it depends on machine config. Please check this for more info – http://www.testautomationguru.com/jmeter-tips-tricks-for-beginners/
Can you write a post or a video to functional test REST API calls GET, POST, PUT, PATCH, DELETE and validate responses in Jmeter.
Not load test…
Pass data for POST, PUT, PATCH via excel and validate the responses in detail. like data driven
I want to perform functional rest API testing on Jmeter and then load test those api’s just by increasing users.
Will be a extremely helpful to others as well
I thought most of the information was already here. Yes, I could add more information on the data-driven testing part.
Congrats, you save my week!