Data-Driven Rest Assured API Testing With Public APIs

Pre-Requisites

Project Setup

Once all of the prerequisites are set up and in order, the next step is to create a new project in Eclipse.

Creating a Maven Project in Eclipse

Creating a new Maven project in Eclipse is a simple process, but it may not be as clear at first. Once Eclipse is open, you want to go to File → New → Other...

Creating a New Maven Project

Now, you want to search for "Maven" and select Maven Project

Searching for Maven Project

To keep it simple, click the checkbox for "Create a simple project" which skips the archetype selection. You can learn more about Maven Archetypes here, but for now, we will just create a simple project.

Create a simple project

Then you can hit "Next". Now, you need to fill in the Group Id, Artifact Id, and Name. I kept all of these the same and put "restAssured-PublicAPI," but you can learn more about Naming Conventions here.

2020-07-22 13_23_19-OurNewMavenProject.png

Now, you can hit "Finish" and you have created a simple Maven project. This is what your file structure should look like after creating your Maven project:

restAssured-PublicAPI Maven Project File Structure - Eclipse IDE.png

Updating the Pom.xml

There are a few additional dependencies that we need to make sure we have installed. Open the pom.xml file that should be within the file structure of your project and we can add some extra dependencies.

Go to the Maven Repository and search for each of the listed dependencies and add them to the project's pom.xml file. Make sure to get the latest stable version of each.

Dependencies

Once done you can save the pom.xml file and it will install the additional dependencies. This is what your pom.xml file should look like with the dependencies:

restAssured-PublicAPI - pom.xml Dependencies - Eclipse IDE.png

File Structure

The file structure is important because it allows us to separate concerns and keep organized. The best way to start is to name packages and organize associated Java classes within them. For this project, we are going to have a package for our Data that will be provided for our tests and a package for the public API tests themselves.

It is important to think through the goal of your project as you create names. We will be using a public API called Regres to create data-driven Rest Assured API tests. These are just some simple names, but feel free to name your files more structured if you would like.

Naming Packages and Classes

  • Package Name: DataForTests.package
    • Class Name: Data.java
  • Package Name: PublicAPITests.package
    • Class Name: Test_GET.java
    • Class Name: Test_POST.java
    • Class Name: Test_DELETE.java

This is what your file structure should look like after adding the packages and classes:

restAssured-PublicAPI - File Structure After Adding Classes.png

Creating the Test Classes

Now, that we have set up our project and created our file structure, we can start actually adding code to our files. We can start with our test classes. For this example, we are only going to create tests for the GET, POST, and DELETE API calls. Feel free to create more and experiment if you like.

Before we start though, we need to make sure we understand the Public API we will be using. Keep in mind that you can technically use any Public API, but depending on the API there may be more steps you need to go through to access it. We will be using Regres, which is open and available for testing purposes just like this. If you visit the website you can see examples of the different types of API calls you can make and the responses you should get back, as well as the endpoint URLs and the response status codes. It is a nice tool for testing!

You can click on the Request URL to see the data within the API. It can be helpful to take a look at the data because it will make it easier to understand how to access the data in code for later. It is also just generally good to take a look at and to understand general API structures. You can also get a JSON viewer extension for your browser to make the JSON easier to read/interpret.


In each Test class, I will share the code and include the comments that help make the code easier to follow and read. Here are a few points to keep in mind:
  • Static imports make working with Rest Assured much cleaner and easier.
  • Using Gherkin Syntax incorporates aspects of Behavior-Driven Development and is much easier to read and understand.
    Here is a good explanation on how to think of/use the Gherkin syntax with Rest Assured - the full article can be found here:

    2020-07-22 14_19_23-REST Assured Tutorial_ How to test API with Example.png


  • Each test class will extend the Data.java class so that we can access the data providing methods, but to do so (since it is in a separate package) we have to import the Package.Classname
  • The dataProvider which is attached to the TestNG 's @Test annotation is already defined for some of these Test methods. The DataProvider will be defined later on, but you can run these same exact tests without the Data Provider, but you would need to hardcode the data in yourself.
  • Learn more about assertThat() which is useful for verifying response data with Rest Assured
  • Understanding Status Codes is an important aspect of API testing because it can help you make positive and negative tests and gain a better understanding of the results.

Test_GET Class

In the GET class, the first test method can be run without the Data Provider. This is useful as a way to test to make sure everything is working. The use of the Rest Assured's baseURI is so that you do not have to type the full endpoint within the given(). The Gherkin syntax makes the tests easy to follow and read. The second test method uses the Data Provider and we are taking in a specific userID that we can use in our API test call. We also use a Hamcrest Matcher containsString in our second test method as a way to check to see that our user GET is successful (with a 200 Status Code) and that the email field in the response body for the user actually contains an "@" symbol - making it most likely an email. Of course, we can do further tests and checks on the data here, but this shows how we can use Hamcrest Matchers to do more sophisticated testing on API response data.

package PublicAPITests;

//Makes it so that you no longer need to use a RestAssured object 
import static io.restassured.RestAssured.*;

import static org.hamcrest.Matchers.*;

import org.testng.annotations.Test;

import DataForTests.Data;

public class Test_GET extends Data {
 
 // We will be using this Public API for our tests: https://reqres.in/
 
 @Test
 public void get_Users() {
 
 // Set the baseURI
 baseURI = "https://reqres.in/api/";
 
 // We can now use Gherkin Syntax to create our tests
 given(). 
 // We need a parameter to specify which page of users we want to pull from
 param("page", "1").
 when().
 // Now we need to reference the endpoint we are referring to in edition to the baseURI
 get("users").
 then(). 
 // Now we can run a test to check that the Status Code is 200 - which indicates success
 assertThat().
 statusCode(200).
 // Then we can log the information we received within the body so that we can check to make sure everything worked as intended.
 log().body();
 }
 
 @Test(dataProvider="DataForGet")
 public void get_User(int userID) {
 
 // Set the base URI
 baseURI = "https://reqres.in/api/";
 
 // Now we can do the same to grab specific users using the Data Provider
 given().
 when().
 get("users/"+userID). 
 then().
 assertThat().
 statusCode(200).and().
 body("data.email", containsString("@")).
 log().body();
 }
}

Test_POST Class

In the POST class, we need a few more imports because we are going to be using JSON simple to help us create a body for our POST request. A POST request for this API allows us to create a new user. So, we can name the method accordingly. We also will be using the Data Provider here so that we can accept the data necessary to create a new user. If you go to the Regres website and select the POST request option, it will show you that it needs a user's name and the user's job in order to create a new user. So we can create our method parameters with this in mind. Then we can use these variables for our test. For a successful POST request, we are looking for a status code of "201", so we can base our test off of that and log the results if we received the correct status code.

package PublicAPITests;

//Makes it so that you no longer need to use a RestAssured object 
import static io.restassured.RestAssured.*;

import org.json.simple.JSONObject;
import org.testng.annotations.Test;

import DataForTests.Data;
import io.restassured.http.ContentType;

public class Test_POST extends Data {
 
 @Test(dataProvider="DataForPost")
 public void create_User(String userName, String userJob) {
 // Set the baseURI
 baseURI = "https://reqres.in/api/";
 
 // For a POST request you need to create a body
 JSONObject request = new JSONObject();
 
 // Initialize the values for the request
 request.put("name", userName);
 request.put("job", userJob);
 
 given().
 // We are sending a JSON request
 header("Content-Type", "application/json").
 contentType(ContentType.JSON).
 // We are also accepting a JSON response
 accept(ContentType.JSON).
 // We need to convert our request into JSON and add it to the body of our request
 body(request.toJSONString()). 
 when().
 // We need to specify that this is a POST request
 post("https://reqres.in/api/users"). 
 then().
 // Assert that the Post Request was successful and log the results if so
 assertThat().
 statusCode(201).and().
 log().ifStatusCodeIsEqualTo(201);
 }
 
}

Test_DELETE Class

The DELETE class is much simpler. We can use the Data Provider here to gives us the userID of the users that we want to delete. Then we can check for the correct status code to make sure that the DELETE request was successful.

package PublicAPITests;

//Makes it so that you no longer need to use a RestAssured object 
import static io.restassured.RestAssured.*;

import org.testng.annotations.Test;

import DataForTests.Data;


public class Test_DELETE extends Data {

 @Test(dataProvider="DataForDelete")
 public void delete_User(int userID) {
 
 // Set the baseURI
 baseURI = "https://reqres.in/api/";
 
 // We do not need to specify a given if it is not necessary
 when().
 delete("users/"+userID).
 then().
 assertThat().
 statusCode(204);
 }
}

The DataProvider Class

Data Class

Now that we have all three of our test classes set up, we can create our Data.java class that provides all of the data for our tests. A Data Provider can be useful because instead of having to hardcode everything and make lots of changes for various tests, you can instead just update the Data.java file to include the updates and the test methods can stay unchanged. It also makes it easier to test multiple sets of data. In the Data.java class, you will need to import the TestNG 's DataProvider and provide names for each method. These names must match the associated test methods in the Test classes. We use Java Objects to hold the data because Java Objects can hold various types of data.

package DataForTests;

// The TestNG DataProvider
import org.testng.annotations.DataProvider;

public class Data {
 
 // Within our Data Class we can create individual methods that will feed data into our individual API call classes
 
 @DataProvider(name = "DataForGet")
 public Object [] dataForGet() {
 // Now we can return an object that gives us a specific User IDs
 return new Object [] {
 1,2,5,8
 };
 }
 
 @DataProvider(name = "DataForPost") 
 public Object[][] dataForPost() {
 // Return Objects that can be used for Post Requests
 return new Object[][] {
 {"Roxas", "Associate Quality Assurance Tester"},
 {"Kairi", "QA Manager"} 
 };
 
 }
 
 @DataProvider(name = "DataForDelete")
 public Object [] dataForDelete() {
 // Now we can delete specific Users based on their ID
 return new Object [] {
 954,328
 };
 }

}

Running Our Tests

Now, that we have set up the Test classes and the Data Provider we can run our TestNG tests. In each Test class you can right-click -→ Run As -→ TestNG Test.

2020-07-22 15_42_04-eclipse-workspace -Running the Tests .png

The console should show you all of the logged information and the "Results of running class Class Name" tab should show you the TestNG Test results. If everything worked correctly the tests should pass successfully. I usually go in order. I run my GET tests and then my POST tests. Then I look at the console for the results of the POST test and grab those "ids" to test my DELETE test.

2020-07-22 15_50_40-eclipse-workspace - restAssured-PublicAPI Test NG Test Results.png

You can experiment by testing for different status codes or results and see what happens if the tests fail. You can even add more API test classes and Data methods in general such as PUT and PATCH. The goal is to get comfortable and understand how to use Rest Assured to test API calls with a public API.

Conclusion

I hope this little overview was useful to anyone who comes across it. This is a demonstration of the experimentation and learning I have gone through so far with Java API testing and is in no way a full representation of the topic, but instead, a representation of my own understanding and research so far as I continue to learn more about the topic.

References and Resources

-- JennTillman - 21 Jul 2020
Topic attachments
I Attachment Action Size Date Who Comment
2020-07-22 12_57_07-CreatingaNewMavenProject.pngpng 2020-07-22 12_57_07-CreatingaNewMavenProject.png manage 30 K 22 Jul 2020 - 17:03 UnknownUser  
2020-07-22 13_11_43-CreateaSimpleProject.pngpng 2020-07-22 13_11_43-CreateaSimpleProject.png manage 17 K 22 Jul 2020 - 17:15 UnknownUser  
2020-07-22 13_11_43-SearchForMavenProject.pngpng 2020-07-22 13_11_43-SearchForMavenProject.png manage 16 K 22 Jul 2020 - 17:13 UnknownUser  
2020-07-22 13_23_19-OurNewMavenProject.pngpng 2020-07-22 13_23_19-OurNewMavenProject.png manage 17 K 22 Jul 2020 - 17:24 UnknownUser  
2020-07-22 14_19_23-REST Assured Tutorial_ How to test API with Example.pngpng 2020-07-22 14_19_23-REST Assured Tutorial_ How to test API with Example.png manage 16 K 22 Jul 2020 - 18:20 UnknownUser  
2020-07-22 14_26_10-Reqres - A hosted REST-API Get Examples.pngpng 2020-07-22 14_26_10-Reqres - A hosted REST-API Get Examples.png manage 16 K 22 Jul 2020 - 18:26 UnknownUser  
2020-07-22 15_42_04-eclipse-workspace -Running the Tests .pngpng 2020-07-22 15_42_04-eclipse-workspace -Running the Tests .png manage 60 K 22 Jul 2020 - 19:42 UnknownUser  
2020-07-22 15_49_42-eclipse-workspace - restAssured-PublicAPI - Get TEST Console -.pngpng 2020-07-22 15_49_42-eclipse-workspace - restAssured-PublicAPI - Get TEST Console -.png manage 52 K 22 Jul 2020 - 19:51 UnknownUser  
2020-07-22 15_50_40-eclipse-workspace - restAssured-PublicAPI Test NG Test Results.pngpng 2020-07-22 15_50_40-eclipse-workspace - restAssured-PublicAPI Test NG Test Results.png manage 27 K 22 Jul 2020 - 20:16 UnknownUser  
2020-07-22 15_50_40-eclipse-workspace - restAssured-PublicAPI <a class="foswikiNewLink" href="/bin/edit/Automation/TestNG?topicparent=Automation.DataDrivenRestAssuredAPITestingWithPublicAPIs" rel="nofollow" title="Create this topic">TestNG</a> Test Results.pngpng 2020-07-22 15_50_40-eclipse-workspace - restAssured-PublicAPI TestNG Test Results.png manage 27 K 22 Jul 2020 - 20:16 UnknownUser  
restAssured-PublicAPI - File Structure After Adding Classes.pngpng restAssured-PublicAPI - File Structure After Adding Classes.png manage 7 K 22 Jul 2020 - 18:02 UnknownUser  
restAssured-PublicAPI - pom.xml Dependencies - Eclipse IDE.pngpng restAssured-PublicAPI - pom.xml Dependencies - Eclipse IDE.png manage 20 K 22 Jul 2020 - 17:47 UnknownUser  
restAssured-PublicAPI Maven Project File Structure - Eclipse IDE.pngpng restAssured-PublicAPI Maven Project File Structure - Eclipse IDE.png manage 6 K 22 Jul 2020 - 17:28 UnknownUser  
Topic revision: r4 - 15 Dec 2020, NicoleRadziwill
© 2020 Ultranauts - 75 Broad Street, 2nd Floor, Suite 206, New York, NY 10004 - info@ultranauts.co