DEV Community

Luiz Eduardo Martins for Mercedes-Benz.io

Posted on • Originally published at mercedes-benz.io

API Testing with Java and Spring Boot Test - Part 2: Improving the solution

In the last part of this step-by-step, we created the project, set up the test framework and also did all the configurations needed to run our API tests.

You can see the first part of the series here:

Let's continue to grow our test framework, but first, we need to do some improvements to the existing code. In this guide, we'll:

  • Refactor the object mapping (to be easier to handle with the JSON files)
  • Improve the response validations
  • Handle multiple environments inside our tests.

These changes will let our code base cleaner and easier to maintain while helping us to create a scalable framework of API tests.

Let's do it.

Homer Simpson woo hoo

Refactoring the Object mapping

We'll take advantage of using the Spring boot Repository to separate the responsibility of mapping the objects (JSON) we're going to use inside our tests. That way, we can do another step forward in our code cleanup.

So, first of all, we're going to:

  • Create a new package called repositories
  • Then we create a new Class inside this package called FileUtils.

We'll also take the opportunity to change the way we map the object to not be hard-coded but be in a proper resource file. That way when we need to change the test data, we don't have to change the test but only the correspondent resource file.

As you can see in the file above, we created a function to read a JSON file and then return the object already mapped - similar to the approach we had before in the test file.

Now, we'll structure the resources folder to accommodate the JSON files.

In the resources folder, let's create a new directory called user and then create a file to store the request body of the operation we'll do.

After that, we need to update our test. Now we want to get the file data by using the new function we created for that purpose.

The updated test will look like that:

Much better! By keeping the code cleaner, we are helping our future selves with its maintenance - trust me, you'll be very glad to see this.

Improving the response validation

Great! Now, let's have a look at the response validation.

In some cases, we want to check the full response body - or at least some parts of it - to fulfill the test requirements.

To do that, we'll create:

  • A new Repository to abstract the responsibility and help us check the full JSON response body
  • A function to handle the check of the JSON response.

We'll also add the "jsonassert" dependency to assert the JSON.

The pom.xml file will look like that:

The newly created ResponseUtils class will be something like this:

The next step should be to use this new function and improve our test. To do that, we'll configure a GET request on YourApiService and return the full Response object. Then we should be able to check the response body.

public Response getRequest(String endpoint) {

    return RestAssured.given(spec)
        .contentType(ContentType.JSON)
    .when()
        .get(endpoint);
}
Enter fullscreen mode Exit fullscreen mode

Now, it's just a matter of adding the test case to the ApiTest test class and using the same strategy of letting the JSON response file be in its proper directory. Finally, we'll have something like this:

@Test
public void testGetUser() throws IOException, JSONException {

    Response res = yourApiService.getRequest("/users/2");

    JsonNode expectedResponse = FileUtils.readJsonFromFile("responses/user/specific.json");

    assertThat(res.statusCode(), is(equalTo(200)));
    ResponseUtils.assertJson(res, expectedResponse);
}
Enter fullscreen mode Exit fullscreen mode

Quite easy to understand if you just look at the test case :)

Homer Simpson relieved

Executing the tests over multiple environments

Now we have the tests properly set, and everything is in the right place. One thing that could be in your mind right now is: "Ok, but I have a scenario in my product in which I need to run my test suit over multiple environments. How do I do that?".

And the answer is - property files.

The property files are used to store specific data which we can use along our test suit, like the application host, port, and path to the API. You can also store environment variables to use within your test framework. However, be careful since we don't want to make this information public. You can see an example in the lines below.

With Spring boot, we take advantage of using the "profiles" to set the specifics of the environments our application has, and make them available as Spring boot profiles.

So, let's do that. Inside the resources folder, we'll create a new file called application-prod.properties to store the values of the production cluster of the test application. The file will store something like this:

apitest.base.uri=https://reqres.in
apitest.base.path=/api
apitest.token=${TOKEN}
Enter fullscreen mode Exit fullscreen mode

Now, the only thing missing is to change our service to get the values stored in the property file.

To get the values from the property files, we'll use the annotation @Value. This annotation will provide the values from the properties we set in the application-prod.properties file.

*Bear in mind: * You'll need to set the environment variable before using it here. The @Value annotation will grab this value from the environment variables you have set.

The updated version of YourApiService class will look like this:

That's a great step up. This way, if you have multiple environments in your setup, you just need to create another application-YOUR_PROFILE_NAME.properties.

Executing the test suit

You must be wondering: How do I run the test suit with this newly created profile?

The answer is simple, just execute mvn clean test -Dspring.profiles.active=prod.

By default, if you just run the mvn clean test command, Spring Boot will try to find a file called application.properties and automatically activate it.

Now we have significantly improved the test setup of our application by:

  • The refactoring of the Object mapping to clean up our code and apply some best practices
  • Improving the response validation by adding a new dependency and using it to simplify the check
  • Learning how to handle multiple test environments. This should be useful when it comes to companies that have layers of environments before the code reach production

Are you curious about the article? Building a Java API test framework part 3 will further improve our application. We will then go deeper into the following topics:

  • Test reporting with Allure reports
  • Configure a CI pipeline with GitHub actions
  • Publish the test report on GitHub pages

See you soon!

Top comments (0)