Testing REST services with REST Assured

For those of you wanting to add the possibility to validate RESTful web services to your test automation framework, REST Assured can be a very useful way to do just that. In this post, I want to show you how to perform some basic tests on both JSON and XML-based REST services.

Installing and configuring REST Assured is easy, just download the latest version from the website and add the relevant .jar files to your testing project and you’re good to go.

Testing a REST service that returns XML
First, let’s try validating a REST service that returns a response in XML format. As an example, I use the ParaBank REST service to get the customer details for a customer with ID 12212 (click here to invoke the service and see the response in your browser). For this response, I want to check that the returned customer ID is equal to 12212, that the first name is equal to John, and that the last name is equal to Doe. The following REST Assured-test does exactly that. Note that the test consists of just a single statement, but I’ve added some line breaks to make it more readable.

package com.ontestautomation.restassured.test;

import static com.jayway.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class RestServiceTest {
	
	public static void main (String args[]) {
		
		get("http://parabank.parasoft.com/parabank/services/bank/customers/12212/").
		then().
			assertThat().body("customer.id", equalTo("12212")).
		and().
			assertThat().body("customer.firstName", equalTo("John")).
		and().
			assertThat().body("customer.lastName", equalTo("Doe"));		
	}
}

Pretty straightforward, right? All you need to do is invoke the service using get() and then perform the required checks using assertThat() and the equalTo() matcher (which is part of Hamcrest by the way, not of REST Assured). Identifying the response elements to be checked is done using a dot notation. For example, customer.id identifies the id element that is a child of the customer element, which is the root element of the response message.

When we run this test, we see the results displayed neatly in our IDE:
REST Assured test resultsOne of the assertions fails, since the actual last name for customer 12212 is Smith, not Doe.

Testing a REST service that returns JSON
REST Assured can be used just as easily to perform checks on REST services that return JSON instead of XML. In the next example, I use a REST service that takes a text string and returns the md5 checksum for that string, together with the original string.
REST service with JSON responseThe following code example checks both the original string value and the md5 checksum value for this REST service:

package com.ontestautomation.restassured.test;

import static com.jayway.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class RestServiceTestGherkin {
	
	public static void main(String args[]) {
		
		given().
			parameters("text", "test").
		when().
			get("http://md5.jsontest.com").
		then().
			body("md5",equalTo("098f6bcd4621d373cade4e832627b4f6")).
		and().
			body("original", equalTo("incorrect"));
	}
}

As you can see, checking values from JSON responses is just as straightforward as is the case for XML responses. Two additional things do have changed in this example though:

  • As this web service call takes parameters – in this case a single parameter containing the string for which the md5 value is to be calculated – we need to define the value of this parameter before calling the service. This is done using the parameters() method, which takes parameter key-value pairs as its argument. Alternatively, we could have omitted the parameters call and just perform a get(“http://md5.jsontest.com?text=test”) instead, but this is both more elegant and more maintainable.
  • Also, as you can see from this example, in REST Assured, you can specify your tests in a BDD format using the Given-When-Then construction that is also used (for example) in Cucumber.

When we run this test, again, the test results show up nicely in our IDE:
Test results for JSON REST service testI’ve added another defect on purpose to show how they are displayed: the value of the original element in the response should of course be test instead of incorrect.

Combining REST Assured and TestNG
Finally, we can also combine REST Assured with TestNG to create an even more powerful REST service testing framework. In that way, you can for example use the reporting capabilities of TestNG for your REST service tests, as well as integrate REST Assured tests into an existing test framework. Doing so is as easy as replacing the default Hamcrest assertions with TestNG assertions and performing the required checks:

package com.ontestautomation.restassured.test;

import static com.jayway.restassured.RestAssured.*;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.jayway.restassured.path.xml.XmlPath;

public class RestServiceTestNG {
	
	@Test
	public void testng() {
		
		// Get the response XML from the REST service and store it as a String
		String xml = get("http://parabank.parasoft.com/parabank/services/bank/customers/12212/").andReturn().asString();
		
		// Retrieve the values to be checked from the XML as a String
		XmlPath xmlPath = new XmlPath(xml).setRoot("customer");
		String customerId = xmlPath.getString("id");
		String firstName = xmlPath.getString("firstName");
		String lastName = xmlPath.getString("lastName");
		
		// Perform the required checks
		Assert.assertEquals(customerId, "12212");
		Assert.assertEquals(firstName, "John");
		Assert.assertEquals(lastName, "Doe");
	}
}

When using TestNG, we first store the response of the web service as a String, after which we can check whatever we want to check. It does make the test code a little longer, and in my personal opinion a little less elegant. On the upside, we can now seamlessly integrate our REST Assured-tests in a larger TestNG-based test framework and profit from the automatic report generation that TestNG provides.

Running this test results in the following output in our IDE:
Test results for TestNG-based testsand the following HTML report:
HTML results for the TestNG-based REST Assured testsAdditional features
Apart from the options shown above, REST Assured provides some other features that can come in very handy when testing REST-based web services. For instance, you can also test services that require authentication in order to be invoked. For basic authentication, you can simply add the credentials to your test statement as follows:

given().auth().basic("username", "password").when().

It is also possible to invoke services that require OAuth authorization (this requires the help of the Scribe library):

given().auth().oauth(..).when().

If you want to explicitly validate that a web service returns the correct content type (JSON, in this case), you can do this:

get("/path/to/service").then().assertThat().contentType(ContentType.JSON)

For a complete overview of all REST Assured features, you can refer to the online documentation.

Happy REST testing!

60 thoughts on “Testing REST services with REST Assured

  1. Bas, I’ve been doing REST API testing using chrome plugin: POSTMAN.

    This is a good start for me to begin with REST automation. Thanks a lot for this post!!!

    My main concern is how to deal with Input JSON for PUT and POST call which are bigger. I’ll go through Rest-assured docs and find it out.

    BTW, thank you so much!!!

    • Hi Ganajan,

      you’re welcome! You make a very good point, I’ve skipped over the PUT and POST operations because I mainly wanted to show how to validate responses. If you find an elegant way of constructing the requests for PUT and POST operations, by all means do post them here for me and others to learn.

      Thanks,

      Bas

  2. Hi,
    I tried example mentioned in Combining REST Assured and TestNG.

    But am getting “java.net.UnknownHostException:parabank.parasoft.com” error messahe.

    Can you please help me resolving this issue.

    • Hi Narendra,

      probably you need to configure proxy settings in your code before you call the Parabank REST service. Does your browser require configuring a proxy for you to be able to navigate to http://parabank.parasoft.com? If so, then you’ll also need to add lines similar to these in your test setup:

      System.setProperty(“http.proxyHost”, “yourproxyhost”);
      System.setProperty(“http.proxyPort”, “yourproxyport”);

      where yourproxyhost and yourproxyport need to be replaced with the correct values. If your proxy requires authentication, then you also need these:

      System.setProperty(“http.proxyUser”, yourproxyuser);
      System.setProperty(“http.proxyPassword”, yourproxypassword);

      Let me know if that solves your problem!

  3. Hi,

    I am new to Rest Assured I just tried to use the example you have given in my local machine. I added jars as well but i am getting error at then(). did i miss anything please help me.

    • Hi Siva,

      could you post the error message and stack trace you’re getting? Might have something to do with the Hamcrest libraries (those are used to perform the assertions in the then() method..)

  4. Hi Bas,

    Your blogs are really helpfull.I have a doubt here.can we build our own utils which we can use to test all the services.I am trying to develop a api test framework on java, http libraries, gradle and jenkins and needed some inputs like what are the common utils we can think of.
    We have some tools like restassured , jersey etc but i wanted to develop a framework which will only use httpclient libraries and it will give the dev or tester the freedom to write the code in pure programming language

    your help would be highly appreciated

    • Hi Ajay,

      of course you can do that, although I am not entirely sure why you would want to do that. What do you want to be able to do that is not offered by existing tools such as REST Assured? As Alan Richardson said once in a keynote I attended: don’t build frameworks, solve problems.

      Curious as to your response!

  5. Hi Bas,

    I need to automate RESTful api which needs OAuth2 and later need to use access token for CURD calls.

    Can you please share sample code , which will help me in getting started ?

    I looked into demo project of rest-assured , but don’t have this scenario covered

    Thanks in advance.

    Regards,
    Vikram

    • Hi Vikram,

      have you checked this page? Or possibly this one?

      If not, is the service you’re working with publicly available? I’d love to try some things out myself.. I haven’t actually worked with an OAuth2 enabled service before.

      • Hi Bas,

        Thanks for quick reply ,
        I tried below today

        curl -H “X-Access-Token: XXXXXX07236415e5afa181211fdd37e4074c9a936ef28cad079137XXXXXX” -H “X-Client-ID: b1e84f01bc7b80f0f482” https://a.wunderlist.com/api/v1/user

        this works fine , now I want to achieve same in test case

        @Test
        public void oAuth2(){
        given().
        auth().preemptive().oauth2(“XXXXXX07236415e5afa181211fdd37e4074c9a936ef28cad079137XXXXXX”).
        when().
        get(“https://a.wunderlist.com/api/v1/user”).
        then().
        statusCode(200);
        }

        above always returns 403

        How can I pass Client-ID to make is working ?

        Thanks,
        Vikram

        • I could get it working as below

          @Test
          public void oAuth2(){
          given().headers(“X-Access-Token”,”XXXXXX07236415e5afa181211fdd37e4074c9a936ef28cad079137XXXXXX”,”X-Client-ID”,”b1e84f01bc7b80f0f482″).
          auth().oauth2(“XXXXXX07236415e5afa181211fdd37e4074c9a936ef28cad079137XXXXXX”).
          when().
          get(“https://a.wunderlist.com/api/v1/user”).
          then().
          statusCode(200);
          }

          Will push demo github repo with all scenarios sooner

  6. Hello Sir,

    am getting the below exception when i execute the test cases.

    FAILED: testng
    java.lang.NoClassDefFoundError: org/apache/http/HttpRequest
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)

    below is the test program..
    package com.ontestautomation.restassured.test;

    import static com.jayway.restassured.RestAssured.*;

    import org.testng.Assert;
    import org.testng.annotations.Test;

    import com.jayway.restassured.path.xml.XmlPath;

    public class RestServiceTestNG {

    @Test
    public void testng() {

    // Get the response XML from the REST service and store it as a String
    String xml = get(“http://localhost:8080/UserManagement/rest/book/Bahula”).andReturn().asString();

    // Retrieve the values to be checked from the XML as a String
    XmlPath xmlPath = new XmlPath(xml).setRoot(“book”);
    String customerId = xmlPath.getString(“name”);

    // Perform the required checks
    Assert.assertEquals(customerId, “Welcome Bahula”);

    }
    }

    Note: i have placed http client jar in lib folder , still facing the same issue. please suggest ..

    • Two questions:

      1. Is the HttpClient jar in your classpath? Just copying it to a lib folder might not be enough
      2. Is the HttpRequest class defined in the HttpClient jar? Check the documentation on the Apache site for that..

  7. Hi,
    The below is my xml tag, please let me know how do I print the value of name is Chennai. I have tried with current.city.name but it only prints null values. Thanks in advance.

    IN

    • Hi Antonypremj,

      could you please try and post your XML tag again (or possibly even the API call you’re making so I can try and reproduce)?

  8. Hi Bas,

    Your blog is really informative and helpful. Kudos for that.
    My current problem is as follows, hope u might have faced similar situation.
    Via selenium webdriver I am populating a form and then clicking a Submit button.
    This action fires a rest service namely Register.json
    I can see in browser Network tool, the response of this service. I need to extract token number from this response.
    Is it possible without firing Response.json service via Rest Assured ( since when webdriver clicks the Submit button, the request Register.json get executed automatically)?

    • Hey Sandeep,

      my solution would be to NOT use Selenium to fill in the form, but do a POST (I assume that’s the action that’s being triggered when you click the submit button) using REST Assured or any other API-level library. This way it’s easier to capture the response and extract the value you need, and you can simply pass the values you fill in the form as parameters in REST Assured.

      The actual functionality you’re testing is not on the browser level (it’s the API), so ideally you shouldn’t use the browser to test it.

  9. Hi Bas,

    I’m getting error at then().It shows error of undefined method for type response.I had imported all the dependency jar.

    Please help me.Thanks in advance..!

  10. Hi Bas, thanks for a great post on Rest assured. I myself am using it.

    The service tests that I have created are run in multiple environments, and most of them pass, however for the occasional fail (Not necessarily an assert fail), but maybe due to a different body or header, how to analyse the point of fail and report the discrepancies.

    • Hi Pijush, I think proper failure analysis can only be done through debugging the failing tests and seeing what happens. Automatic failure analysis and reporting is tough!

      If your tests are failing on some environments because of a different header, does that mean your tests aren’t as good as they can be or that the API you’re testing has some inconsistencies?

  11. Hi ,
    How do i assert an xml response root element
    If Request succeed only root element exists in Response body.
    Need help Thanks in advance

  12. That’s nice document Bas. I am wondering how can I add assertion to the headers in restAssured?
    We throw error code and error message in “Warnings” header of response.
    Please let me know if you need more detail.

    Thanks.

    • So there’s a response header with header name ‘Warnings’ and a value that contains any warnings returned by the API provider?

      In that case you can simply do then().assertThat().header(“Warnings”,equalTo(“”)); or whatever other assertion you’d like to perform. See also the official documentation here.

  13. Hi Bas,

    With the above provided “given when then” approach for rest api testing, How can I write feature files in cucumber. My project specific need is to write feature files for api testing as cucumber provides good reporting

    • Hey Dp,

      I haven’t found an elegant way of combining the fact that Cucumber separates step definitions for Given, When and Then in separate methods, whereas REST Assured does everything in a single method. I can think of a couple of ways of doing this, but I don’t like them. I’d rather combine REST Assured with a test framework such as TestNG, which has some decent reporting options as well.

      If you really need to use Cucumber, you could simply store the resulting object from the given() (a RequestSpecification object) into a variable and pass this into the when() step. Similar with the step from when() to then() (but then it’s a RequestSender object). Again, I don’t like it, but it can be done.

  14. Hi Bas,

    We are doing POC to test micro services, i want to know how feasible rest assure is, compare to SOUP UI and could you please give us example to create mock services using rest assure???.

    • Hey Harish,

      what format / protocol are your microservices talking? If they talk REST then you can use REST Assured. In that case, SoapUI can be used too, but even though both are created to write tests for APIs, I find them to be very different and target different types of users. REST Assured is great when you have some Java development skills and are looking to create tests that should be run in a CI/CD pipeline. SoapUI is more targeted towards users with less programming experience.

      Oh, and you can’t use REST Assured to create mock services, it’s only purpose is for testing. If you’re looking for an easy to use tool for creating mock services, have a look at WireMock.

  15. Pingback: RESTful API Testing – VikramVI Knowledge Sharing

  16. Sir , I am new to REST API automation testing and would like to learn more in detail using REST Assured.
    Please can you suggest any other blog/site for me to learn it from beginner’s perspective.

  17. Hi Bas,

    Can you please give us some examples for using “annotations” in feature file examples area. like below

    @smoke
    Examples:
    | test data|

    @Regression
    Examples:
    | test data|

    • Hi Bharan,

      What does this have to do with REST Assured?

      Also, what you’re referring to are tags. They’re not used on the examples level, but on the scenario or feature level. You can easily tell Cucumber or SpecFlow to run (or to not run) scenarios or features that have specific tags. In that way you can create clusters of tests, for example when you want to run all tests during the night and just a small set during the day after a developer checks in a piece of code.

  18. Hi Bas,

    Our compay want to use RestAssured for API testing. I could learn a lot from your post. I could say its wonderful. I want to learn more about post and patch op. Can you plz provide some more knowledge.

    • Hi Manju, thanks for the kind words! There are a couple more posts on REST Assured on my blog, simply do a search on the home page for them.

    • Using POST and PATCH can be done in the same way really, the only thing that’s different is how to create the request bodies.

  19. Hi Bas,

    Actually my API needs basic autorization headers after login with credentials. After authentication will get session id in Headers of the response. How to capture that and how to be passed for the rest of APIs as authorization id.

    Please let me know. In Rest Assured API format.

    Thanks,
    Sateesh N.V

    • Somehow you’ll need to extract the header value and reuse that, don’t remember off the top of my head if the extract() method can do that for you.

Leave a Reply

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