Authoring first rest api test

APIs under test

Let us use Reqres as our APIs under test.

Typical steps to author an API test

  1. Get to know the API under test.
  2. Configure the API end-point under test
  3. Generate request and response classes
  4. Generate a client class that would invoke the API under test
  5. Generate a Test class. Add test method & Execute

Get to know the API under test

Let us get familiar with an API that returns details of a particular user. Here is the end-point URL for the same.

https://reqres.in/api/users/2

Let us use postman to understand the details of this API

In postman create a new request with the https://reqres.in/api/users/2 as url & execute. The response has a HTTP status of 200 with response body detailing the user requested for.

Response of the API with user details:

{
    "data": {
        "id": 2,
        "email": "janet.weaver@reqres.in",
        "first_name": "Janet",
        "last_name": "Weaver",
        "avatar": "https://reqres.in/img/faces/2-image.jpg"
    },
    "support": {
        "url": "https://reqres.in/#support-heading",
        "text": "To keep ReqRes free, contributions towards server costs are appreciated!"
    }
}

Please open the code tab on the right side of postman window and choose cURL from the dropdown as shown in below image. This would show the generated cURL command for the request.

Configure the API end-point under test

Open src/test/resources/api/hosts.json and specify baseUrl as below.

{
  "baseUrl": "https://reqres.in/"
}

Generate response classes

Lets us create a package called getUser under api. Also, let us create model package under getUser that holds response class

Let us generate model class. From postman, copy the response JSON of the API to the clipboard.

Right-click on the getUser/model package, choose New → Generate POJO from JSON



  1. Paste the JSON response from clipboard.
  2. Choose Lombok.
  3. Enter Root object name as GetUserResponse.
  4. Click Generate button.


This would generate POJO classes representing the JSON.


Note: Please replace the @Data annotation of Lombok with @Getter in all the three generated classes.

Generate a client class that would invoke the API under test

Right-click on the getUser package, choose New → Ekam Component → Retrofit Client. Enter name as GetUser. Hit Enter.

Move the generated class under getUser package as shown below


This will generate GetUserClient as shown below:

package ekam.example.api.getUser;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import retrofit2.Call;
import retrofit2.http.*;
import io.qameta.allure.okhttp3.AllureOkHttp3;
import com.testvagrant.ekam.reports.annotations.APIStep;

public class GetUserClient extends RetrofitBaseClient {

    private interface GetUserService {
    }

    private final GetUserService service;

    @Inject
    public GetUserClient(@Named("baseUrl") String baseUrl) {
        super(baseUrl, new AllureOkHttp3());
        service = httpClient.getService(GetUserService.class);
    }
}

Generate Service method

Place the cursor within the interface body. Press Control + Enter (or Code → Generate… menu option) to invoke the below popup.
Choose the “Ekam Retrofit2 Signature Generator” option.


This will open up a dialog “Retrofit API signature generator“

  1. Enter operation as getUser
  2. Enter Response model as GetUserResponse. Please note that, this model class has been created in the previous step
  3. Switch to postman window and copy the cURL command to clipboard. Paste it in the cURL textbox as shown in below image

Hit OK button. This will generate the signature of the getUser API. Resolve GetUserResponse and format the code to look as below.

        @GET("https://reqres.in/api/users/2")
        Call<GetUserResponse> getUser(
        );

Let us edit the url to remove the baseUrl and format as below:

        @GET("/api/users/2")
        Call<GetUserResponse> getUser();


The complete file would look like below.

package ekam.example.api.getUser;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import ekam.example.api.getUser.model.GetUserResponse;
import retrofit2.Call;
import retrofit2.http.*;
import io.qameta.allure.okhttp3.AllureOkHttp3;
import com.testvagrant.ekam.reports.annotations.APIStep;

public class GetUserClient extends RetrofitBaseClient {

    private interface GetUserService {

        @GET("/api/users/2")
        Call<GetUserResponse> getUser();

    }

    private final GetUserService service;

    @Inject
    public GetUserClient(@Named("baseUrl") String baseUrl) {
        super(baseUrl, new AllureOkHttp3());
        service = httpClient.getService(GetUserService.class);
    }
}

Generate a method to invoke GetUser API

Let us generate a method that would invoke GetUser API. Press Control+Enter (Code → Generate…) and choose Ekam Retrofit2 API Step Generator


This will open up a dialog “Retrofit API step generator“
  1. Enter operation as getUser
  2. Enter Response model as GetUserResponse.
  3. Switch to postman window and copy the cURL command to clipboard. Paste it in the cURL textbox as shown in below image

Hit OK button. This will generate the signature of the getUser API. Resolve GetUserResponse and format the code to look as below.

    @APIStep(keyword = "When", description = "I invoke getUser API")
    public GetUserResponse getUser() {
      Call<GetUserResponse> call = service.getUser();
      Response<GetUserResponse> response = httpClient.executeAsResponse(call);
      GetUserResponse getUserResponse = response.body();
      return getUserResponse;
    }

The UserClient class would like as below:

package ekam.example.api.getUser;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import ekam.example.api.getUser.model.GetUserResponse;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.*;
import io.qameta.allure.okhttp3.AllureOkHttp3;
import com.testvagrant.ekam.reports.annotations.APIStep;

public class GetUserClient extends RetrofitBaseClient {

    private interface GetUserService {

        @GET("/api/users/2")
        Call<GetUserResponse> getUser();
    }

    private final GetUserService service;

    @Inject
    public GetUserClient(@Named("baseUrl") String baseUrl) {
        super(baseUrl, new AllureOkHttp3());
        service = httpClient.getService(GetUserService.class);
    }

    @APIStep(keyword = "When", description = "I invoke getUser API")
    public GetUserResponse getUser() {
      Call<GetUserResponse> call = service.getUser();
      Response<GetUserResponse> response = httpClient.executeAsResponse(call);
      GetUserResponse getUserResponse = response.body();
      return getUserResponse;
    }
}


Generate Test

Now that our Client class is ready, let us add a test calling this API

Right-click on getUser package choose New → Ekam Component


In the Ekam component popup, select "API Test" & enter the name as `GetUserTests`


This will generate a test as shown below
package ekam.example.api.getUser;

import com.testvagrant.ekam.testBases.testng.APITest;
import static com.testvagrant.ekam.commons.LayoutInitiator.*;
import org.testng.annotations.Test;
import io.qameta.allure.TmsLink;
import static org.testng.Assert.*;

public class GetUserTests extends APITest {

    @TmsLink("Test case id")
    @Test(groups = "api", description = "Test case description")
    public void apiTest() {

        // 1. Arrange

        // 2. Act

        // 3. Assert

    }
}

Let us call the getSingleUser method in the UserClient



Here is the complete code of the test.

package ekam.example.api.getUser;

import com.testvagrant.ekam.testBases.testng.APITest;
import static com.testvagrant.ekam.commons.LayoutInitiator.*;
import ekam.example.api.getUser.model.GetUserResponse;
import org.testng.Assert;
import org.testng.annotations.Test;
import io.qameta.allure.TmsLink;
import static org.testng.Assert.*;

public class GetUserTests extends APITest {

    @TmsLink("Test case id")
    @Test(groups = "api", description = "Test case description")
    public void shouldReturnUser() {

        // 1. Arrange

        // 2. Act
        GetUserResponse user = Client(GetUserClient.class).getUser();

        // 3. Assert
        Assert.assertNotNull(user.getData().getEmail());

    }
}

Execute Test

We need to make an IntelliJ IDEA setting change to execute tests via IDE

Preferences → Build, Execution, Deployment → Build Tools → Gradle

Run tests using: IntelliJ IDEA



Execute the test from IDE



Congratulations!! on your first test