Quality and efficiency: how to run automated Rest API testing with an AI tool

Cover of the article "Quality and efficiency: how to run automated Rest API testing with an AI tool". In the picture, young programmer writing a program code sitting at the workplace with three monitors in the office.
Discover how to do automated Rest APIs testing (Java, Maven, Cucumber, Restassured) with an AI tool, StackSpot AI.

Artificial intelligence (AI) has transformed the design and execution of automated Rest API testing. By applying Machine Learning (ML) and natural language processing techniques, AI can analyze vast data sets and API specifications to generate comprehensive and relevant test cases automatically. This speeds up the testing process and increases its effectiveness by identifying unexplored quality areas.

In this article, you’ll learn how to use StackSpot AI’s contextualized code assistant to create automated Rest API testing, simplifying the development and coding of automation projects.

Getting to know StackSpot AI

StackSpot is a development platform that empowers engineering teams to modernize legacy systems and deliver value faster by centralizing and reusing technology standards, generating highly contextualized code through AI, and optimizing the cloud journey. It is divided into three offerings: StackSpot EDP, StackSpot Cloud Services, and StackSpot AI (the latter is the focus of this article).

StackSpot AI can use your context, Knowledge Sources, and tech decisions to generate more assertive, high-quality suggestions. Moreover, the AI assistant enables the creation of quick commands to automate repetitive tasks. Say goodbye to generic suggestions and adopt hyper-contextualized code generation!

The best part: StackSpot AI has a freemium plan. Use the web version or download the IDE extensions (IntelliJ or Visual Code) to get started! 

Automated Rest API testing: first steps with StackSpot AI

In this article, we’ll create a Rest API test automation project using Java, Restassured, Cucumber, and Maven.

We’ll use a personal account (GitHub) to access the StackSpot AI portal, download the AI contextualized code assistant Plugin, and add the development tool (IntelliJ).

The AI contextualized code wizard will help generate the initial project code based on the questions and context, suggesting code to add to the project.

Finally, we’ll add new test scenarios and refactor the code, making our project more comprehensive and reusable for the software community.

So, let’s get started:

Log in to the StackSpot AI Login page. An account created on GitHub is necessary for this step.

You will see this initial screen within the StackSpot AI environment:

Image from the article on automated Rest API testing. StackSpot AI environment after authentication, where in the open photo we have the website; on the left a menu with options for using the tool "Home, Stacks AI, Quick Command, Knowledge Sources, Workspaces, Analytics;" in the center, we have a welcome message, as well as the IDEs available to download "Visual Studio Code and IntelliJ," with the "IntelliJ" option being used; and on the right an example video of the first steps to use the StackSpot AI tool.

Defining the installation

For the installation, follow the recommended guidelines for building the test automation:

IDE

IDE Plugin

Language

Dependencies

Maven libraries

Creating the automated Rest APIs testing project

To create and run the Rest API test automation project, follow the guidelines.

1 – Creating a new project for automated Rest API tests

After completing the installations (previous step), simply:

  • Access IntelliJ IDE.
  • Go to the File menu and choose “New -> Project”.
  • Click on New Project and the “Java” option.
  • Fill in the Name field with the name of the project.
  • Click on Build System and choose “Maven”.

That’s it! The Rest API test automation project has been created.

Image from the article on automated Rest API testing. IntelliJ IDE for creating a project for test automation of Rest API, where in the open photo we have the IDE; on the left a menu with options for use to create a project in the IntelliJ tool, being "New Project" the options "Java, Kotlin, Groovy, Empty Project", where we choose "Java"; and on the right we have fields to fill in the project "Name, Location, Build System, JDK", where we select the options in Build System the option "Maven and JDK the option "11"; and at the bottom of the screen the "Create" button to create the project with the defined settings.

2 – Authenticating with StackSpot AI

With the IntelliJ IDE already open and the project already created (previous step), simply:

  • Access the StackSpot AI plugin.
  • Fill in the email field of your GitHub account.
  • Click on the “Continue with GitHub” button.
  • Click the “Yes” button on the screen that opens. After receiving confirmation, return to IntelliJ.

That’s it! After authentication, you can use StackSpot AI.

Image from the article on automated Rest API testing. IntelliJ IDE with StackSpot AI Plugin. In the photo at the top, we have the IDE, and on the right, the StackSpot AI Plugin with the "Email" field and the "Continue with email" and "Continue with Github" buttons. We will use the email from our Github account and activate the "Continue with Github" button to authenticate.

Image from the article on automated Rest API testing. Site requesting permissions to use the StackSpot AI Plugin, where in the open photo, we have the site, with the "No" and "Yes" buttons, where we press the "Yes" button to accept the permissions and establish the connection of the Plugin, site, and IDE.

Image from the article on automated Rest API testing. The site is confirming acceptance of permissions to use the StackSpot AI Plugin, where in the open photo, we have the site with the confirmation message "Device Authenticated Successfully," and we are ready to use the plugin in the IDE.

3 – Generating code

With the project already created in the IntelliJ IDE and logged in to StackSpot AI (previous step), simply:

That’s it! The code has been generated, and we can add it to the project created for use.

Image from the article on automated Rest API testing. IntelliJ IDE with StackSpot AI Plugin, in the image, we have the IDE with chat for interaction. We asked the question, "Generate an example for POST test of Rest API, using Java 11, Maven, Rest Assured, and Cucumber." We got an answer with code examples to copy to the project created.

Adding the code generated by StackSpot AI to the project

Let’s add the generated code to the project for automated Rest API testing, following the steps below:

1. Configure the project with Maven

In your project’s pom.xml file, add the following dependencies for Cucumber, JUnit, and RestAssured.

Java
pom.xml

<dependencies>

       <!-- RestAssured -->

       <dependency>

           <groupId>io.rest-assured</groupId>

           <artifactId>rest-assured</artifactId>

           <version>4.3.3</version>

           <scope>test</scope>

       </dependency>

       <!-- Cucumber -->

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-java</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-junit</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <!-- JUnit -->

       <dependency>

           <groupId>junit</groupId>

           <artifactId>junit</artifactId>

           <version>4.13.2</version>

           <scope>test</scope>

       </dependency>

   </dependencies>

2. Create the test scenario with Cucumber

Create a feature file for Cucumber. 

Java
src/test/resources/features/postFeature.feature

Feature: Test POST API endpoint

 Scenario: Post new data to the API

   Given I set POST API endpoint

   When I send POST HTTP request

   Then I receive valid HTTP response code 201

3. Implement the test with RestAssured

Now, implement the test steps using RestAssured. Create a test class corresponding to your Cucumber scenario.

Java
src/test/java/stepDefinitions/PostApiSteps.java

package com.example.steps;

import io.cucumber.java.en.Given;

import io.cucumber.java.en.When;

import io.cucumber.java.en.Then;

import io.restassured.RestAssured;

import io.restassured.response.Response;

import static org.junit.Assert.*;

public class PostApiSteps {

   private Response response;

   @Given("I set POST API endpoint")

   public void i_set_post_api_endpoint() {

       RestAssured.baseURI = "http://yourapi.com/api";

   }

   @When("I send POST HTTP request")

   public void i_send_post_http_request() {

       response = RestAssured.given().contentType("application/json")

               .body("{\"key\": \"value\"}")

               .when().post("/endpoint");

   }

   @Then("I receive valid HTTP response code 201")

   public void i_receive_valid_http_response_code_201() {

       assertEquals(201, response.getStatusCode());

   }

}

4. Setting up Runner with Cucumber

Create a class to run the Cucumber tests.

Java
src/test/java/cucumberOptions/TestRunner.java

package com.example;

import io.cucumber.junit.Cucumber;

import io.cucumber.junit.CucumberOptions;

import org.junit.runner.RunWith;

@RunWith(Cucumber.class)

@CucumberOptions(

       features = "src/test/resources/features",

       glue = "com.example.steps",

       plugin = {"pretty", "html:target/cucumber-reports.html"},

       monochrome = true

)

public class TestRunner {

}

Running automated Rest API tests

To run automated Rest API tests, you can use the Maven command.

mvn test

At this point, you have an example of the code and structure of the integrated Rest API test automation project, making a POST request, receiving a response, and validating the status code. Now, adjust what has been generated according to your needs.

Image from the article on automated Rest API testing. IntelliJ IDE after running the tests. In the open photo, we have the IDE with the file "PostApiTest.feature" and a test scenario created "Post new data to the API" that we generated through StackSpot AI, added to the project, and ran successfully.

Next, we need to improve the code and organize the project, adding the GET request, receiving responses, and validating data.

To do this, use the ServeRest APIs to:

  • Register a new user (POST User)
  • Consult registered user (GET User)
  • Consult unregistered user (GET User)

The adjustments will be demonstrated below, based on the scenarios to be validated.

Refactoring the project to make the implementation more straightforward and organized

To refactor, make the changes below:

1 – Adjusting the project with Maven

Adjust the pom.xml file to contain the implementations.

Java
pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

   <modelVersion>4.0.0</modelVersion>

   <groupId>org.example</groupId>

   <artifactId>StackSpot-api-integration-tests</artifactId>

   <version>1.0-SNAPSHOT</version>

   <properties>

       <maven.compiler.source>11</maven.compiler.source>

       <maven.compiler.target>11</maven.compiler.target>

       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

   </properties>

   <dependencies>

       <!-- RestAssured -->

       <dependency>

           <groupId>io.rest-assured</groupId>

           <artifactId>rest-assured</artifactId>

           <version>4.3.3</version>

           <scope>test</scope>

       </dependency>

       <!-- Cucumber -->

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-java</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-junit</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <!-- JUnit -->

       <dependency>

           <groupId>junit</groupId>

           <artifactId>junit</artifactId>

           <version>4.13.2</version>

           <scope>test</scope>

       </dependency>

       <!-- Java Faker -->

       <dependency>

           <groupId>com.GitHub.javafaker</groupId>

           <artifactId>javafaker</artifactId>

           <version>1.0.2</version>

       </dependency>

   </dependencies>

</project>

2 – Adjusting the test scenario with Cucumber

Adjust the resources/features/user.feature file to contain the implementations.

Java
src/test/resources/features/user.feature

Feature: User API

  @all @user-register

  Scenario: Should register a new user

    Given I have the data to register a new user

    When I make a POST request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 201 to a new user

  @all @user-not-registered

  Scenario: Should query registered user

    Given I do not have a registered user but wish to register

    When I make a GET request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 200 to registered user

  @all @user-non-existent

  Scenario: Should query non-registered user

    Given I do not have a registered user "XPTO"

    When I make a GET request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 400 to non-registered user

3 – Adjusting the test steps with RestAssured

Adjust the file stepDefinitions/UserSteps.java to contain the implementation of the feature’s tests for registering a new user, consulting a registered user, and consulting an unregistered user.

Java
src/test/java/stepDefinitions/UserSteps.java

package stepDefinitions;

import io.cucumber.java.en.Given;

import io.cucumber.java.en.Then;

import io.cucumber.java.en.When;

import io.restassured.response.Response;

import services.UserService;

public class UserSteps {

    private Response response;

    private String body;

    private String idUser;

    private final UserService userService = new UserService();

    @Given("I have the data to register a new user")

    public void i_have_the_data_to_register_a_new_user() {

        body = userService.generateUserData();

    }

    @When("I make a POST request to the URL {string}")

    public void i_make_a_post_request_to_the_url(String url) {

        response = userService.createNewUser(url, body);

    }

    @Then("The response status code should be {int} to a new user")

    public void the_response_status_code_should_be_to_a_new_user(int statusCode) {

        idUser = userService.validateRegisteredUserData(response, statusCode);

    }

    @Given("I do not have a registered user but wish to register")

    public void i_do_not_have_a_registered_user_but_wish_to_register() {

        idUser = userService.checkExistingUser(null);

    }

    @When("I make a GET request to the URL {string}")

    public void i_make_a_get_request_to_the_url(String url) {

        response = userService.queryUser(url, idUser);

    }

    @Then("The response status code should be {int} to registered user")

    public void the_response_status_code_should_be_to_registered_user(int statusCode) {

        userService.validateQueriedUserData(response, idUser, statusCode);

    }

    @Given("I do not have a registered user {string}")

    public void i_do_not_have_a_registered_user(String newUserId) {

        idUser = newUserId;

    }

    @When("I make an attempt to GET request to the URL {string}")

    public void i_make_an_attempt_to_get_request_to_the_url(String url) {

        response = userService.queryUser(url, idUser);

    }

    @Then("The response status code should be {int} to non-registered user")

    public void the_response_status_code_should_be_to_non_registered_user(int statusCode) {

        userService.validateNonRegisteredUserData(response, statusCode);

    }

}

4 – Creating the DTO structure to manipulate the request data

Create the file dto/UserDto to create get/set and access to the object/class attributes.

Java
src/test/java/dto/UserDto.java

package dto;

public class UserDto {

    private String name;

    private String email;

    private String password;

    private String admin;

    // Getter and Setter for name

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    // Getter and Setter for email

    public String getEmail() {

        return email;

    }

    public void setEmail(String email) {

        this.email = email;

    }

    // Getter and Setter for password

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    // Getter and Setter for admin

    public String getAdmin() {

        return admin;

    }

    public void setAdmin(String admin) {

        this.admin = admin;

    }

}

5 – Creating the Service structure to set up the request

Create the file service/UserService.java to set up the requests to be made.

Java
src/test/java/service/UserService.java

package services;

import com.github.javafaker.Faker;

import dto.UserDto;

import io.restassured.path.json.JsonPath;

import io.restassured.response.Response;

import static io.restassured.RestAssured.given;

import static org.junit.Assert.assertEquals;

public class UserService {

    private Response response;

    private String requestBody;

    private String userId;

    private UserDto userDto;

    private Faker faker;

    private String newUserId;

    public String generateUserData(){

        faker = new Faker();

        userDto = new UserDto();

        userDto.setName(faker.name().name());

        userDto.setEmail(faker.internet().emailAddress());

        userDto.setPassword("123456");

        userDto.setAdmin("true");

        requestBody = "{\n" +

                \"nome\": \""+userDto.getName()+"\",\n" +

                \"email\": \""+userDto.getEmail()+"\",\n" +

                \"password\": \""+ userDto.getPassword()+"\",\n" +

                \"administrador\": \""+ userDto.getAdmin()+"\"\n" +

                "}";

        return requestBody;

    }

    public Response createNewUser(String url, String requestBody){

        response = given()

                .header("Content-type", "application/json")

                .and()

                .log().all()

                .body(requestBody)

                .when()

                .post(url)

                .then()

                .log().all()

                .extract().response();

        return response;

    }

    public String validateRegisteredUserData(Response response, int statusCode){

        JsonPath jsonPathEvaluator = response.jsonPath();

        assertEquals(statusCode, response.getStatusCode());

        userId = jsonPathEvaluator.get("_id");

        return userId;

    }

    public String checkExistingUser(String userId){

        String newBody;

        Response newResponse;

        if (userId == null){

            newBody = generateUserData();

            newResponse = createNewUser("https://serverest.dev/usuarios",newBody);

            newUserId = validateRegisteredUserData(newResponse, 201);

        }

        else{

            newUserId = userId;

        }

        return newUserId;

    }

    public Response queryUser(String url, String newUserId){

        response = given()

                .header("Content-type", "application/json")

                .and()

                .log().all()

                .when()

                .get(url + "/" + newUserId)

                .then()

                .log().all()

                .extract().response();

        return response;

    }

    public void validateQueriedUserData(Response response, String newId, int statusCode){

        JsonPath jsonPathEvaluator = response.jsonPath();

        if (newUserId.equals(newId)) {

            assertEquals(statusCode, response.getStatusCode());

            assertEquals(newUserId, jsonPathEvaluator.get("_id"));

        }

        else {

            assertEquals(userDto.getName(), jsonPathEvaluator.get("name"));

            assertEquals(userDto.getEmail(), jsonPathEvaluator.get("email"));

            assertEquals(userDto.getPassword(), jsonPathEvaluator.get("password"));

            assertEquals(userDto.getAdmin(), jsonPathEvaluator.get("admin"));

            assertEquals(statusCode, response.getStatusCode());

            assertEquals(userId, jsonPathEvaluator.get("_id"));

        }

    }

    public void validateNonRegisteredUserData(Response response, int statusCode){

        assertEquals(statusCode, response.getStatusCode());

    }

}

Running the tests after refactoring

To run the tests, you can use the Maven command.

 mvn test

Image from the article on automated Rest API testing. IntelliJ IDE after refactoring and running the tests. In the open photo, we have the IDE with the file "user.feature." Three scenarios were executed: "Must register new user," "Must consult registered user," and "Must consult unregistered user." Based on the initial code generated by StackSpot AI, we refactored the code, making improvements. We ran it, and it was successful.

That’s it! The adjusted project has been successfully executed. With the help of StackSpot AI, scenarios were written more effectively, code reuse was promoted, and automated Rest API tests were simplified.

Watch the video tutorial on YouTube:

Conclusion

This article shows the advantages of embracing a contextualized artificial intelligence tool like StackSpot AI in automated Rest API testing processes. By integrating the right AI tool, the entire software development cycle has gained speed and efficiency. Software Quality processes also reaped major benefits from the new features in this scenario.

Using StackSpot AI, it has been possible to adopt assertive suggestions based on their own standards and sources of knowledge. This brings unprecedented efficiency, reliability, and innovation to their automated Rest API testing and QA processes.

Do you have any questions or suggestions? Please leave us a comment!

References

Consume innovation,
begin transformation

Subscribe to our newsletter to stay updated
on the latest best practices for leveraging
technology to drive business impact

Related posts