Logging in Rest Assured

HOME

Logging plays an important role in understanding the behaviour of the test. When we are testing an API, it is good to know how the APIs are behaving, how the request is made how we received the response from the API, what the headers look like, what the body looks like, and what parameters are we providing to the request. All of this helps us in debugging the test code and to identify the reason for the failure of the test.

REST Assured, provide support to a different type of logging as shown below:-

Request Logging

To log all request specification details including parameters, headers, and body of the request, log().all() needs to be added to post given() section.

import org.testng.annotations.Test;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;

public class RestTests {
	
	@Test
    public void requestLoggingDemo() {
 
        String json = "{\"name\":\"apitest\",\"salary\":\"5000\",\"age\":\"30\"}";
 
        // GIVEN
        given()
               .log().all()
               .baseUri("https://dummy.restapiexample.com/api")
               .contentType(ContentType.JSON)
               .body(json)
 
        // WHEN
         .when()
                .post("/v1/create")
 
        // THEN
          .then()
                 .assertThat()
                 .statusCode(200)
                 .body("data.name", equalTo("apitest"))
                 .body("message", equalTo("Successfully! Record has been added."));
 
    }

}

The output of the above program is

Other different request logging options are:-

given().log().params(). .. // Log only the parameters of the request
given().log().body(). .. // Log only the request body
given().log().headers(). .. // Log only the request headers
given().log().cookies(). .. // Log only the request cookies
given().log().method(). .. // Log only the request method
given().log().path(). .. // Log only the request path

Response Logging

If you want to print the response body regardless of the status code, you can do

get("/x").then().log().body()..

This will print the response body regardless of an error occurring.

import org.testng.annotations.Test;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;

public class RestTests {

  @Test
	public void responseLoggingDemo() {

		String json = "{\"name\":\"apitest\",\"salary\":\"5000\",\"age\":\"30\"}";

		// GIVEN
		given()
              .baseUri("https://dummy.restapiexample.com/api")
              .contentType(ContentType.JSON)
			  .body(json)

		 // WHEN
		  .when()
                 .post("/v1/create")

		// THEN
		  .then()
                 .log().all()
                 .statusCode(200)
                 .body("data.name", equalTo("apitest"))
				 .body("message", equalTo("Successfully! Record has been added."));

	}
}

The output of the above program is

Conditional Logging

What if you want to perform logging conditionally? For example, you want to log in only if validation fails if the status code is equal to 200, or if the server returned a status code >=400.

.then().log().ifStatusCodeIsEqualTo(302). .. // Only log if the status code is equal to 302
.then().log().ifStatusCodeMatches(matcher). .. // Only log if the status code matches the supplied Hamcrest matcher
import org.testng.annotations.Test;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;

public class RestTests {
	
	@Test
	public void conditionalResponseLoggingDemo() {

		String json = "{\"name\":\"apitest\",\"salary\":\"5000\",\"age\":\"30\"}";

		// GIVEN
		given()
               .baseUri("https://dummy.restapiexample.com/api")
               .contentType(ContentType.JSON)
			   .body(json)

		// WHEN
		 .when()
               .post("/v1/create")

		// THEN
		 .then()
                .log().ifStatusCodeIsEqualTo(200)
                .assertThat().statusCode(200)
				.body("data.name", equalTo("apitest"))
                .body("message", equalTo("Successfully! Record has been added."));

	}

}

The output of the above program is

Logging to a text file with Rest Assured

We will see how we can log all the request and response data to a txt file using Rest Assured.

  1. Create a PrintStream object. You have to provide an object of FileOutputStream() to the PrintStream() constructor. Provide the path to the logging.txt file in FileOutputStream().
  2. REST Assured gives us a filter() method, this filter method accepts RequestLoggingFilter and ResponseLoggingFilter. They have two methods, logRequestTo() and logResponseTo() methods respectively. These methods expect a Stream.
  3. Pass the log stream we created to these methods.
import org.testng.annotations.Test;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class RestTests {
	
	@Test
	public void responsetoFileDemo() throws FileNotFoundException {

		PrintStream log = new PrintStream(new FileOutputStream("logging.txt"));

		String json = "{\"name\":\"apitest\",\"salary\":\"5000\",\"age\":\"30\"}";

		// GIVEN
		given()
               .baseUri("https://dummy.restapiexample.com/api")
               .contentType(ContentType.JSON)
				.body(json)
                .filter(RequestLoggingFilter.logRequestTo(log))
				.filter(ResponseLoggingFilter.logResponseTo(log))

		// WHEN
		 .when()
                .post("/v1/create")

		// THEN
          .then()
                 .log().ifStatusCodeIsEqualTo(200)
                 .assertThat().statusCode(200)
				 .body("data.name", equalTo("apitest"))
                 .body("message", equalTo("Successfully! Record has been added."));

	}
}

Mostly we have more than 1 test, and we want to save the log of all the tests in the text file. We can create a @BeforeClass method, and this class contains the code to create the file and append the data to that file.

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.equalTo;

public class LogTest {
	
	 public PrintStream log ;
	 RequestLoggingFilter requestLoggingFilter;
	 ResponseLoggingFilter responseLoggingFilter;
	
	@BeforeClass
	public void init() throws FileNotFoundException {
		
		 log = new PrintStream(new FileOutputStream("test_logging.txt"),true);	
		 requestLoggingFilter = new RequestLoggingFilter(log);
		 responseLoggingFilter = new ResponseLoggingFilter(log);
		 
	}
	
	@Test
	public void test1() {

		// Given
		given()

         .contentType(ContentType.JSON)
         . filters(requestLoggingFilter,responseLoggingFilter)
       
          .when()
             .get("https://dummy.restapiexample.com/api/v1/employee/2")
				
           .then()
           		.log().ifStatusCodeIsEqualTo(200)
           		.assertThat().statusCode(200).statusLine("HTTP/1.1 200 OK")
				
           		// To verify booking id at index 2
				.body("data.employee_name", equalTo("Garrett Winters"))
				.body("message", equalTo("Successfully! Record has been fetched."));
	}
	
	@Test
	public void test2() {

		// Given
		given()

         .contentType(ContentType.JSON)
         . filters(requestLoggingFilter,responseLoggingFilter)
       
          .when()
             .get("https://dummy.restapiexample.com/api/v1/employee/1")
				
           .then()
           .log().ifStatusCodeIsEqualTo(200)
           .assertThat().statusCode(200).statusLine("HTTP/1.1 200 OK")
				// To verify booking id at index 1
				.body("data.employee_name", equalTo("Tiger Nixon"))
				.body("message", equalTo("Successfully! Record has been fetched."));
	}

	
	
	@Test
    public void test3() throws FileNotFoundException {
 
        
        String json = "{\"name\":\"apitest\",\"salary\":\"5000\",\"age\":\"30\"}";
 
        // GIVEN
        given()
               .baseUri("https://dummy.restapiexample.com/api")
               .contentType(ContentType.JSON)
                .body(json)
               .filters(requestLoggingFilter,responseLoggingFilter)
 
        // WHEN
         .when()
                .post("/v1/create")
 
        // THEN
          .then()
                 .log().ifStatusCodeIsEqualTo(200)
                 .assertThat().statusCode(200)
                 .body("data.name", equalTo("apitest"))
                 .body("message", equalTo("Successfully! Record has been added."));
 
    }
	
}

The below file shows that the log for multiple requests is saved here.

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

How to test PATCH Request using Rest Assured
How to test POST request from JSON Object in Rest Assured
How to test POST JSON Object request using Java Map in Rest Assured
How to create JSON Array Request Body – org.json
Assertion of JSON in Rest Assured using Hamcrest
Extraction from JSON in Rest Assured

6 thoughts on “Logging in Rest Assured

  1. One question, suppose if we use single txt file “logging.txt” across the framework. It is capturing only last test case request & response details but not appending previous test cases request & response in same txt file “logging.txt” . Can you please share the code on this. Thanks.

    Like

    1. Hi, You can add a @BeforeClass method and place the ode to create the file and append the data to the file in that method. I have added a sample code in the tutorial for your reference. Hope you find it useful

      Like

  2. For logging “Logging to a text file with Rest Assured” instead of FileOutputStream, FileInputStream has written into the steps mentioned. But in code it clearly mentioned the FileOutputStream.

    Like

Leave a comment