0

I have a test class with multiple methods written in RestAssured and TestNG. And I want to execute these methods sequentially in a loop. How can we do that?

The requirement is to fill up a train. I have an API which gives me the number of seats available on a train. Knowing that number, I want to run a loop such that it executes a few test methods like do a journey search, create a booking, make the payment and confirm the booking sequentially every time. So lets say if we have 50 seats available, I want to run the test 50 times where each loop executes each of the methods sequentially.

This is my sample code:

public class BookingEndToEnd_Test {

RequestSpecification reqSpec;
ResponseSpecification resSpec;
String authtoken = "";
String BookingNumber = "";
........few methods....

@BeforeClass
public void setup() {
    ......
}

@Test
public void JourneySearch_Test() throws IOException {

    JSONObject jObject = PrepareJourneySearchRequestBody();

    Response response = 
            given()
            .spec(reqSpec)
            .body(jObject.toString())
            .when()
            .post(EndPoints.JOURNEY_SEARCH)
            .then()
            .spec(resSpec)
            .extract().response();


    }

@Test(dependsOnMethods = { "JourneySearch_Test" })
public void MakeBooking_Test() throws IOException, ParseException {

    JSONObject jObject = PrepareProvBookingRequestBody();

    Response response = 

     given()
     .log().all()
    .spec(reqSpec)
    .body(jObject.toString())
    .when()
    .post(EndPoints.BOOKING)
    .then()
    .spec(resSpec)
    .extract().response();

}

@Test(dependsOnMethods = { "MakeBooking_Test" })
public void MakePayment_Test() throws IOException, ParseException {

    JSONObject jObject = PreparePaymentRequestBody();

    Response response = 
     given()
    .spec(reqSpec)
    .pathParam("booking_number", BookingNumber)
    .body(jObject.toString())
    .when()
    .post(EndPoints.MAKE_PAYMENT)
    .then()
    .spec(resSpec)
    .body("data.booking.total_price_to_be_paid", equalTo(0) )
    .extract().response();



}

@Test(dependsOnMethods = { "MakePayment_Test" })
public void ConfirmBooking_Test() throws IOException {
    Response response = 
            (Response) given()
    .spec(reqSpec)
    .pathParam("booking_number", BookingNumber)
    .when()
    .post(EndPoints.CONFIRM_BOOKING)
    .then()
    .spec(resSpec)
    .extract().response();

}



}

I tried using invocationCount = n. But that executes the method n number of times however I want to run other test methods in sequence first and then run this test second time.

@Test(invocationCount = 3)
public void JourneySearch_Test() throws IOException {

Can someone help me on how I can run the test class with multiple test methods in a loop please?

Mihir
  • 491
  • 5
  • 21
  • Do you need to call `@BeforeClass` before each sequence of tests OR can it be called only once? – Fenio Aug 06 '19 at 14:43
  • @Fenio: It can be called just once. I have methods that generate authtoken value that is used in the header for the API calls I make within every method within the class. – Mihir Aug 06 '19 at 16:37
  • @Fenio: Could you also give your advice on the below mentioned solution please? – Mihir Aug 19 '19 at 22:29
  • Try to ask a new question as always :) – Fenio Aug 20 '19 at 04:17
  • Since it was a continuation of the solution provided below, ive added a comment here so that anyone reading this would get the complete flow with the solutiom. If I asked a new question , It would repeating the same question and seeking advice. Would you still advice me to ask a new question @Fenio? – Mihir Aug 20 '19 at 05:43
  • Yes. Because this topic is close and the answer is accepted. If you need further instructions, that should be in a new topic. If the provided answer still needs more explanation then it should be accepted. – Fenio Aug 20 '19 at 05:45
  • Ok sure. Thanks for the reasoning. I shall create a new question. Thanks @Fenio – Mihir Aug 20 '19 at 05:50
  • @Fenio - https://stackoverflow.com/questions/57567494/running-a-testng-class-file-with-many-dependent-test-methods-multiple-times-sequ – Mihir Aug 20 '19 at 06:03

1 Answers1

1

You can do this easily using a @Factory that is powered by a data provider.

Here's a working example that demonstrates how to work with @Factory (you can tweak this example to suite your needs).

import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;

public class SampleTestClass {

  private int iteration;

  @Factory(dataProvider = "dp")
  public SampleTestClass(int iteration) {
    this.iteration = iteration;
  }

  // Change this to @BeforeClass if you want this to be executed for every instance
  // that the factory produces
  @BeforeTest
  public void setup() {
    System.err.println("setup()");
  }

  @Test
  public void t1() {
    System.err.println("t1() => " + iteration);
  }

  @Test
  public void t2() {
    System.err.println("t2() ==>" + iteration);
  }

  @DataProvider(name = "dp")
  public static Object[][] getData() {
    return new Object[][] {{1}, {2}, {3}, {4}};
  }
}
Krishnan Mahadevan
  • 14,121
  • 6
  • 34
  • 66
  • thank you very much for the solution. I shall try and this out and keep you posted. Thanks once again. – Mihir Aug 07 '19 at 09:12
  • the data I want to be read is an excel sheet with some columns and rows. I have 3 test methods where the 2nd one depends on the output of the 1st one, 3rd one depends on the output of the first one. However only the first test method needs to read data from the excel sheet. Is there a way when we return a new object from the data provider, we return it from an excel input?@Krishnan – Mihir Aug 19 '19 at 21:43
  • Can you help me on https://stackoverflow.com/questions/57572362/setting-invocationcount-from-a-variable please? @Krishnan – Mihir Aug 20 '19 at 15:11