API testing with Java and REST Assured - getting started

REST Assured is an open-sourced Java library that facilitates automated testing of API endpoints. For this post I want to walk through the steps you need to get some basic REST Assured tests up and running on your local machine.

API testing with Java and REST Assured - getting started
Photo by Markus Spiske / Unsplash

Overview

REST Assured is an open-sourced Java library that facilitates automated testing of API endpoints. For this post I want to walk through the steps you need to get some basic REST Assured tests up and running on your local machine.

Before diving into the nuts and bolts of REST Assured, what is API automated testing?

The test pyramid visually depicts test types and gives some general guidelines on how many of each to create. We want lots of unit tests and a small number of end-to-end UI tests.

Alt Text

In the middle of the pyramid is API testing. API tests validate the application from the API level, and do not include the user interface(UI). Because of that, API tests will typically run faster and be less brittle than UI tests.

In the past I’ve used tools such as Postman and Karate to do automated API testing. I've recently starting exploring REST Assured, providing me another API testing tool.

Gherkin and API testing

Gherkin is typically used to describe application behavior from an end-user perspective, and can be used with tools like Cucumber to create automated tests. Gherkin uses the familiar Given/When/Then syntax.

REST Assured uses a fluent style API that leverages those same keywords to provide a common reference point when structuring tests. This will make your tests more readable and easy to understand.

Hello World

So what does a REST Assured test look like? Let's start with the basics.

    @Test
    public void checkEmployeeStatus() {
        // @formatter:off
        given().
        when().
                get("http://dummy.restapiexample.com/api/v1/employees").
        then().
                assertThat().
                statusCode(200);
        // @formatter:on
    }

This example is probably fairly self explanatory. We're just making a GET request and verifying the the status code is 200.

Now let's look at what you need to do to get this simple example running on your machine.

Your OS and IDE

Ultimately we are just building Java classes that will leverage the REST Assured library. You can run the tests on MacOS, Linux or Windows. You'll also need the Java JDK installed.

For the IDE, you can use whatever you are comfortable with. I am using the Community Edition of IntelliJ IDEA, but of course these concepts are going to apply to IDEs like Eclipse, or even a simple text editor. For this walkthrough I will be referencing IntelliJ IDEA.

Creating the Project

Open IDEA and create a new Maven project. To get our simple example running we're going to need to do a couple things.

  • Update your pom file to include the REST Assured and TestNG dependencies:
<dependencies>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>4.2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.3.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
  • Create the Java class in src/test/java:
import org.testng.annotations.Test;

import static io.restassured.RestAssured.given;

public class HelloWorld {

    @Test
    public void checkEmployeeStatus() {
        // @formatter:off
        given().
        when().
                get("http://dummy.restapiexample.com/api/v1/employees").
        then().
                assertThat().
                statusCode(200);
        // @formatter:on
    }
}

Right-click the test method and run the test:
Alt Text

If you get a TestNG error "TestNG by default disables loading DTD from unsecured Url", just follow the instructions in the message and use the argument [-Dtestng.dtd.http=true] in your run config.

Hopefully you see a successful test:
Alt Text

Make the Test Fail

Is this test really doing what we think it is? Let's find out by making it fail. Change the endpoint to something invalid, like http://dummy.restapiexample.com/api/v1/employees-invalid

Run the test again. It should fail with message Expected status code <200> but was <404>. That's good, because that shows our test is working as we expect, and also shows we get a 404 with an invalid endpoint. Go ahead and change back to the valid URL back and again verify it passes.

Now let's create another test with an invalid endpoint to verify we get the expected 404:

@Test
    public void checkInvalidUrlReturns404() {
        // @formatter:off
        given().
        when().
                get("http://dummy.restapiexample.com/api/v1/employees-invalid").
        then().
                assertThat().
                statusCode(404);
        // @formatter:on
    }

Run this test and verify it's green too.

Viewing data Returned from the Endpoint

So now we have a couple basic tests running. Let's go back to our first test with the valid endpoint. What data is returned from that endpoint?

Our current test is not validating any content, and there are no logs to display the returned data. Let's change that by adding log().body() to the test:

@Test
    public void checkEmployeeStatus() {
        // @formatter:off
        given().
        when().
                get("http://dummy.restapiexample.com/api/v1/employees").
        then().
                assertThat().
                statusCode(200).
                log().body();
        // @formatter:on
    }

Run the test. You should see the JSON response in your console log:
Alt Text

That's cool, but in the real world you may only want to log on failures. That can be accomplished with log().ifValidationFails(). Go ahead and update the test to only log if the test fails. The ifValidationFails change needs to be applied prior to validating the status code, like this:

 @Test
    public void checkEmployeeStatus() {
        // @formatter:off
        given().
        when().
                get("http://dummy.restapiexample.com/api/v1/employees").
        then().
                assertThat().
                log().ifValidationFails().
                statusCode(200);
        // @formatter:on
    }

Of course you should verify it's working as expected by making it fail and verifying you get the log.

Code Formatting

You may have noticed that the REST Assured statements are wrapped in @formatter:off and @formatter:on tags. I do this because I like to do indentation underneath the gherkin lines (given/when/then/and), but the IDEA code reformat feature doesn't follow that standard. I turn the formatter off because IDEA code reformat will wipe out my indentation formatting if I don't.

For this to work, I also needed to "enable formatter markers in comments" in code style preferences of IDEA.

Alt Text

Wrap-up

So hopefully that gives you a taste of the power of REST Assured. In my next post I am going to cover some more advanced REST Assured topics such as validating payload, validating JSON schema, and POSTs and DELETEs.

You can find the complete code for this series of blog posts in my Github project.

Happy testing!