JMeter – REST API Testing – A Complete Data-Driven Approach

In this article, I would like to show you a data-driven approach for REST API testing. If you are new to JMeter/REST API Testing, I would like to read this article first to get some idea.

Goal:

Our aim here is to come up with a framework to test REST API with different HTTP Methods. This test will be driven through a spreadsheet and the spreadsheet will contain all the input parameters, API URL, HTTP Method, request JSON, text response should be used for assertion etc.

By using one single HTTP Sampler, we would like to send different types of request GET / POST / PUT / PATCH / DELETE. Even the HTTP Request body data will be added dynamically at run time.

JSON Server:

I am going to use this JSON-Server for this testing purpose.  You can quickly set this up and running within a minute. You could also use your application APIs if you have.

Once it is installed, start the server using below command.
json-server --watch db.json

My db.json looks like this.

{
   "books":[

   ],
   "comments":[

   ],
   "profile":{
      "name":"typicode"
   }
}

Test Scenarios:

Lets assume, we would like to execute these scenarios as part of our REST API functional testing. Test description provides a high level idea about the test case.

rest005

If all requests are actually same and only the data is different as shown below, we could easily do a data-driven testing in JMeter with 1 HTTP Sampler & a CSV DataSet Config.

csv1

But in our case, We have 1 GET request, then 5 POST requests, then 1 GET request…etc. We send different types of request. So, we might end up creating our Test Plan as shown here

rest006

What will happen if we need to test thousands of scenarios!!? How can we maintain such a huge JMeter test?

Data-Driven Testing:

In order to completely drive the testing through a spreadsheet, Lets move any data which could vary among these HTTP requests to the spreadsheet as shown here after carefully analyzing these requests.

rest004

  • #1 – A simple GET request to fetch all the items from the books category. For the first test case, we would not have any data. So, it should respond with empty list.
  • #2-#6 – We add new books with different titles and authors using POST requests. The input.json for these test cases would be as shown here. We would be replacing the title and author at run time with the corresponding data in the spreadsheet.
{
  "title": 	"${title}",
  "author": "${author}"
}
  • #7 & #9 – Simple GET requests for specific book details to check if the POST / PUT requests worked fine.
  • #8 – A PUT request to simply replace the current item in the DB with the given data.
{
  "title": 	"${title}",
  "author": "${author}",
  "price": "$10.00"
}
  • #10 – A PATCH request to specifically update a data of the current item in the DB.
{
  "title": "${title}"
}
  • #11 #12 – A DELETE requests to remove an item from the DB.

As we have moved all the variables to the spreadsheet, now by having only one HTTP Sampler in JMeter test and by setting the HTTP Sampler properties/attributes at run time, we could run the entire test.

JMeter Test Plan:

  • I add a CSV Data Set Config – to read the test scenarios and input parameters.

rest007

 

  • Add a HTTP Sampler and update the details. Let the Method be with some default selection. Also add a Header Manager with Content-Type as application/json

rest008

  • Add a JSR223 – PreProcessor. This should be responsible for changing the HTTP Method based on the value in the spreadsheet. It also sets the HTTP Request body data for POST / PUT / PATCH requests.

dd-rest009

 

The below statements change the current sampler HTTP Method.

def httpMethod = vars.get("http.method");
sampler.setMethod(httpMethod);

We use below statements to change the HTTP Body. We read the input.json file then we replace the any variable with the corresponding data

def dataToBePosted = new CompoundVariable(new File(vars.get("jmeter.test.home") + vars.get("input.json")).text).execute();
def arg= new HTTPArgument("", dataToBePosted, null, true);
arg.setAlwaysEncoded(false);
sampler.getArguments().addArgument(arg);

  • Last step would be to add assertion.

REST

  • Run the test plan.

dd-rest011

Download:

You can check the JMeter test plan here in GitHub.

Summary:

By moving all the variables to a spreadsheet and with 1 HTTP Sampler, we are able to test different types of requests. Adding any new tests to this test plan is very easy. As you already know, we have to insert one more row in the spreadsheet with the enough information for the new test. By looking at the spreadsheet, you can easily understand our coverage. Any update to the test data would also be easy with this approach instead of updating each and every individual HTTP Requests in JMeter.

 

Happy Testing & Subscribe 🙂

 

Share This:

12 thoughts on “JMeter – REST API Testing – A Complete Data-Driven Approach

  1. Thank you yaar. You accepted my request for this post. It will be much easier to functional test and then load test API’s
    This is great stuff.
    Big fan of yours and your blog
    Keep sharing!!!

  2. unable to open this on Jmeter 3.0 getting com.throughworks.xstream.mapper.cannotresolveclassexception:html

  3. I’m trying to understand what “jmeter.test.home” is in reference to in the script, as I’m unable to post the body data from the JSON file…I feel this is what is failing my tests.

    1. jmeter.test.home is a variable which gives the absolute path of the current location of the jmx file. Check the test plan element.

  4. Hi I have done the same set up, i downloaded your project zip through git hub in my local system. When i run the jemter i am getting connection error. How can i fix that.

  5. HI,

    I am unable to start the JSON server, i downloaded ZIP from git and trying given command but it’s not working. Please do the needful.

  6. I have to do some minor changes in the groovy script. I was not using http method variable, I removed.
    compound variable is not needed. Also we need to chose encoding, I have used UTF-8.
    import org.apache.jmeter.engine.util.CompoundVariable;
    import org.apache.jmeter.protocol.http.util.HTTPArgument;

    //set the HTTP request body
    if(!vars.get(“input.json”).equals(“”)){
    def dataToBePosted = new File(vars.get(“jmeter.test.home”) + vars.get(“input.json”)).text;
    //def dataToBePosted = new CompoundVariable(fileContent).execute();

    def arg= new HTTPArgument("", dataToBePosted, null, false, "UTF-8");
    arg.setAlwaysEncoded(false);
    sampler.getArguments().addArgument(arg);

    //HTTP Body is set to
    log.info(dataToBePosted);

    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.