Creating data driven API tests with REST Assured and TestNG

As you’ve probably read in previous posts on this site, I am a big fan of the REST Assured library for writing tests for RESTful web services. In this post, I will demonstrate how to create even more powerful tests with REST Assured by applying the data driven principle, with some help from TestNG.

Combining REST Assured and TestNG
REST Assured itself is a Domain Specific Language (DSL) for writing tests for RESTful web services and does not offer a mechanism for writing data driven tests (i.e., the ability to write a single test that can be executed multiple times with different sets of input and validation parameters). However, REST Assured tests are often combined with JUnit or TestNG, and the latter offers an easy to use mechanism to create data driven tests through the use of the DataProvider mechanism.

Creating a TestNG DataProvider
A TestNG DataProvider is a method that returns an object containing test data that can then be fed to the actual tests (REST Assured tests in this case). This data can be hardcoded, but it can also be read from a database or a JSON specification, for example. It’s simply a matter of implementing the DataProvider in the desired way. The following example DataProvider creates a test data object (labeled md5hashes) that contains some example text strings and their md5 hash:

@DataProvider(name = "md5hashes")
public String[][] createMD5TestData() {
		
	return new String[][] {
			{"testcaseOne", "4ff1c9b1d1f23c6def53f957b1ed827f"},
			{"testcaseTwo", "39738347fb533d798aca9ae0f56ca126"},
			{"testcaseThree", "db6b151bb4bde46fddb361043bc3e2d9"}
	};
}

Using the DataProvider in REST Assured tests (with query parameters)
Using the data specified in the DataProvider in REST Assured tests is fairly straightforward. In the example below, we’re using it in combination with a RESTful web service that uses a single query parameter:

@Test(dataProvider = "md5hashes")
public void md5JsonTest(String originalText, String md5Hash) {
		
	given().
		parameters("text", originalText).
	when().
		get("http://md5.jsontest.com").
	then().
		assertThat().
		body("md5", equalTo(md5Hash));
}

Notice how the data in the DataProvider can be used for specification of expected results just as easy as for specifying input parameters. When we run this test, we can see in the output that the test is run three times, once for every set of input and validation parameters:

Console output for our data driven REST Assured test

Using the DataProvider in REST Assured tests (with query parameters)
The other parameter approach commonly used with RESTful web services is the use of path parameters. Let’s create another DataProvider, this one specifying Formula 1 circuits and the country they are situated in:

@DataProvider(name = "circuitLocations")
public String[][] createCircuitTestData() {
		
	return new String[][] {
			{"adelaide","Australia"},
			{"detroit","USA"},
			{"george","South Africa"}
	};
}

The Ergast Developer API provides motor racing data through a public API (check it out, it’s really cool). Here’s how to parameterize the call to get specific circuit data and check the country for each circuit with REST Assured, again using our DataProvider:

@Test(dataProvider = "circuitLocations")
public void circuitLocationTest(String circuitId, String location) {
		
	given().
		pathParameters("circuitId",circuitId).
	when().
		get("http://ergast.com/api/f1/circuits/{circuitId}.json").
	then().
		assertThat().
		body("MRData.CircuitTable.Circuits[0].Location.country",equalTo(location));
}

The only real difference is in how to set up path parameter use in REST Assured (see also here), otherwise making your tests data driven is just as easy as with query parameters.

When we run this second test, we can see again that it’s run three times, once for every circuit specified:

Console output for our data driven REST Assured test (with path parameters_

A Maven Eclipse project containing the code demonstrated in this blog post can be downloaded here.

23 thoughts on “Creating data driven API tests with REST Assured and TestNG

  1. Have you come across Spock? The Data Driven tests in Spock are real eye-candy. Spock coupled with REST Assured will produce some really useful and expressive tests.

  2. Pingback: Java Web Weekly, Issue 124 | Baeldung

  3. Pingback: Testing Bits – 5/8/16 – 5/14/16 | Testing Curator Blog

  4. Anybody can help me to figure out, how to generate some project for futher import in Postman (my team would like to use my testcases in postman and run it by themself with newman)

    • I have never really looked into Postman so far but I will try and do so this week. I’ll let you know if I find anything that might help you.

  5. Hi Bas,

    Thank you very much for this wonderful article! Do you have any idea about chaining multiple HTTP requests using rest assured? I want to use part of the response from an http request as a parameter for another HTTP request. I am not sure if restAssured has this kind of capability. Thank!

    • Hey Alim, REST Assured can certainly help you there. You can extract parts of the response (individual elements, but blocks of elements as well, pretty much everything that is the result of a GPath query) and reuse it in subsequent steps. See the documentation for the extract() method or my open source workshop (at https://github.com/basdijkstra) for examples.

      • Thank you very much for your kind response Bas! it is really helpful. I just found out that for extensive api testing with very complex json files, it may be better to create java classes for such Json files and map the api response to that Java class using Jackson library together with Rest Assured.

        • Sounds like a decent approach indeed! I’ve written a post on deserializing API responses into POJOs as well, a quick search should point you to that article..

  6. How to do parametrization, when path params are not provided, only header in a get request(example: “/storeno/12232”), the number being the storeid. How to achieve parametrization in this?

    • Hi Moran, I’m not sure I understand your question. Headers are completely different from path parameters, but you can pass both to a REST Assured test through a variable.

      • Hi Mohan, something like this will do the job for you:
        int storeno=12232;
        String path = yourPath + /storeno/{storeno}
        given().pathParam(“storeno”:storeno).when().get(path)

  7. Hi Bas,

    I need to create a data driven test using below requirements but dont know where to start. Can you please help me here. Below are the requirements

    Retrieve and persist a list of random cities distributed worldwide ( this number to consist of several thousand cities). Furthermore, create a framework capable of requesting weather, and currency/forex data using but not limited to open source API’s like: http://openweathermap.org/api; http://www.xignite.com/forex;

    Create a data generator which builds on the city data previously retrieved. This tool should generate a dataset of randomised people (this set is expected to be in thousands), and populate the following fields: “Name, Surname, Address, City, Telephone, Email, Date of birth, Sex, Marital Status, Nationality, Country of birth, Gross annual income, and Currency”. This data must be built against standard regex patterns.

    • Is this a homework assignment? Or an assessment as part of a job interview? It does look that way.

      What have you tried yourself?

    • Out of principle I don’t help people with assignments like these.

      However, I suggest you find an API that can give you a city based on its zip code, because zip codes are numbers and therefore easy to randomize. Example: api.zippopotam.us. Or scrape a site like this: https://www.randomlists.com/random-world-cities

      Build a list of cities and move from there.

      That’s all the help I am willing to give you.

  8. Pingback: REST API Testing – Software QA Automation

Leave a Reply

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