Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API test (Using API Spec) generated by RoostGPT #67

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<!--Plugin added by RoostGPT-->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<outputDirectory>testReport</outputDirectory>
</configuration>
<!--Plugin added by RoostGPT-->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>2.1</version>
<configuration>
<outputDirectory>testReport</outputDirectory>
</configuration>
<!--Plugin added by RoostGPT-->
</plugin>
</plugins>
</build>
<dependencies>
Expand Down Expand Up @@ -61,5 +85,33 @@
<scope>compile</scope>
<!--Dependency added by RoostGPT-->
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
<!--Dependency added by RoostGPT-->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<scope>compile</scope>
<!--Dependency added by RoostGPT-->
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.3.1</version>
<scope>compile</scope>
<!--Dependency added by RoostGPT-->
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
<scope>compile</scope>
<!--Dependency added by RoostGPT-->
</dependency>
</dependencies>
</project>
117 changes: 117 additions & 0 deletions src/test/java/org/springframework/RoostTest/TestdataLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

package org.springframework.RoostTest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Arrays;

// Test Loader loads the data from ENV, Properties File and CSV file in given order.
public class TestdataLoader {

Properties properties = new Properties();

private String fromENV(String name) {
return System.getenv(name);
}

private void loadPropertiesFile() {
String propertiesFileName = this.fromENV("PROPERTIES_FILE");
InputStream content = null;
try {
if (propertiesFileName == null || propertiesFileName.equals("")) {
content = getClass().getClassLoader().getResourceAsStream("application.properties");
} else if (propertiesFileName.contains(File.separator)) {
// handles if PROPERTIES_FILE contains path.
content = new FileInputStream(propertiesFileName);
} else {
// handles if PROPERTIES_FILE is inside src/main/resources folder.
content = getClass().getClassLoader().getResourceAsStream(propertiesFileName);
}
if (content != null) {
this.properties.load(content);
} else {
System.out.println(
"Skip loading from properties file. ENV['PROPERTIES_FILE'] or src/main/resources/application.properties file doesn't exists.");
}
} catch (IOException e) {
String errorMessage = e.getMessage();
System.out.printf("Skip loading from properties file as encountered error : %s" + errorMessage);
}
}

private String fromPropertiesFile(String name) {
return properties.getProperty(name);
}

private List<Map<String, String>> fromCSVFile(String filePath) {
List<Map<String, String>> data = new ArrayList<>();
String delimiter = "\\^\\|\\^";

try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
boolean headerSkipped = false;
List<String> headers = new ArrayList<>();

while ((line = br.readLine()) != null) {
if (!headerSkipped) {
headers.addAll(List.of(line.split(delimiter)));
headerSkipped = true;
continue;
}

String[] values = line.split(delimiter);
if (values.length > 0) {
Map<String, String> row = new HashMap<>();
for (int i = 0; i < Math.min(headers.size(), values.length); i++) {
row.put(headers.get(i), values[i].trim());
}
data.add(row);
}
}
} catch (IOException e) {
String errorMessage = e.getMessage();
System.out.printf("Skip loading from csv file : %s" + errorMessage);
}
return data;
}

public List<Map<String, String>> load(String csvFileName, String[] envVarsList) {
Map<String, String> envMap = new HashMap<>();
List<Map<String, String>> csvData = this.fromCSVFile(csvFileName);
List<Map<String, String>> envVars = new ArrayList<>();
this.loadPropertiesFile();

for (String key : envVarsList) {
envMap.put(key, "");
String value = this.fromENV(key);
if (value != null) {
envMap.put(key, value);
}
value = this.fromPropertiesFile(key);
if (value != null) {
envMap.put(key, value);
}
}
for (Map<String, String> row : csvData) {
Map<String, String> envMapwithCSV = new HashMap<>(envMap);
for (Map.Entry<String, String> entry : row.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (!value.equals("")) {
envMapwithCSV.put(key, value);
}
}
envVars.add(envMapwithCSV);
}
return envVars;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// ********RoostGPT********
/*
Test generated by RoostGPT for test sample_demo_api using AI Type Open AI and AI Model gpt-4

Test generated for /laureate/{laureateID}_get for http method type GET in rest-assured framework

RoostTestHash=56bfcadf64


*/

// ********RoostGPT********
package org.springframework.RoostTest;

import io.restassured.RestAssured;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import java.util.List;
import java.util.Map;
import org.hamcrest.MatcherAssert;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;
import java.util.ArrayList;
import java.util.Arrays;
import static org.hamcrest.Matchers.*;

public class LaureateLaureateIdGetTest {

private List<Map<String, String>> envList;

@BeforeEach
public void setUp() {
TestDataLoader dataLoader = new TestDataLoader();
String[] envVarsList = {"laureateID"};
envList = dataLoader.load("src/test/java/org/springframework/RoostTest/laureate_laureateIDGetTest.csv", envVarsList);
}

@Test
public void laureateLaureateIdGet_Test() throws JSONException {
setUp();
int testNumber = 1;
for (Map<String, String> testData : envList) {
String baseUrl = testData.getOrDefault("BASE_URL", "http://api.nobelprize.org/2.1");
RestAssured.baseURI = baseUrl;
JSONObject requestBodyObject = new JSONObject(testData.getOrDefault("RequestBody", "{}"));
Response responseObj = given()
.pathParam("laureateID", testData.getOrDefault("laureateID", ""))
.when()
.get("/laureate/{laureateID}")
.then()
.extract().response();

validateResponse(testData, responseObj, testNumber++);
}
}

private void validateResponse(Map<String, String> testData, Response responseObj, int testNumber) throws JSONException {
JsonPath response;
String contentType = responseObj.getContentType();
System.out.printf("Test Case %d: laureateLaureateIdGet_Test \n", testNumber);
System.out.println("Request: GET /laureate/{laureateID}");
System.out.println("Status Code: " + responseObj.statusCode());
if (testData.containsKey("statusCode")) {
validateStatusCode(testData, responseObj);
} else {
validateDefaultStatusCode(responseObj);
}
response = extractResponse(responseObj, contentType);
if (response != null) {
validateResponseBody(responseObj, response);
}
}

private void validateStatusCode(Map<String, String> testData, Response responseObj) {
String statusCodeFromCSV = testData.get("statusCode");
if (statusCodeFromCSV.contains("X")) {
MatcherAssert.assertThat(
"Expected a status code of category " + statusCodeFromCSV + ", but got "
+ responseObj.statusCode() + " instead",
String.valueOf(responseObj.statusCode()).charAt(0), equalTo(statusCodeFromCSV.charAt(0)));
} else {
MatcherAssert.assertThat(responseObj.statusCode(), equalTo(Integer.parseInt(statusCodeFromCSV)));
}
}

private void validateDefaultStatusCode(Response responseObj) {
List<Integer> expectedStatusCodes = Arrays.asList(200, 400, 404, 422);
MatcherAssert.assertThat(responseObj.statusCode(), is(in(expectedStatusCodes)));
}

private JsonPath extractResponse(Response responseObj, String contentType) throws JSONException {
if (contentType.contains("application/xml") || contentType.contains("text/xml")) {
String xmlResponse = responseObj.asString();
JSONObject jsonResponse = XML.toJSONObject(xmlResponse);
String jsonString = jsonResponse.getJSONObject("xml").toString();
return new JsonPath(jsonString);
} else if(contentType.contains("application/json")) {
return responseObj.jsonPath();
} else {
System.out.println("Unsupported content type: "+contentType);
return null;
}
}

private void validateResponseBody(Response responseObj, JsonPath response) {
switch (responseObj.statusCode()) {
case 200:
validateSuccessfulResponse(response);
break;
case 400:
validateErrorResponse(response);
break;
case 404:
validateNotFoundResponse(response);
break;
case 422:
validateUnprocessableEntityResponse(response);
break;
default:
System.out.println("Unsupported status code: " + responseObj.statusCode());
}
}

private void validateSuccessfulResponse(JsonPath response) {
// Implement specific assertions for 200 status code
}

private void validateErrorResponse(JsonPath response) {
// Implement specific assertions for 400 status code
}

private void validateNotFoundResponse(JsonPath response) {
// Implement specific assertions for 404 status code
}

private void validateUnprocessableEntityResponse(JsonPath response) {
// Implement specific assertions for 422 status code
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
laureateID^|^RequestBody^|^statusCode
1^|^{"name":"John Doe","age":30,"email":"[email protected]"}^|^400
2^|^{"name":"Jane Smith","age":25,"email":"[email protected]"}^|^404
3^|^{"name":"Bob Johnson","age":35,"email":"[email protected]"}^|^422
4^|^{"name":"Alice Williams","age":28,"email":"[email protected]"}^|^400
5^|^{"name":"Charlie Brown","age":32,"email":"[email protected]"}^|^404
6^|^{"name":"David Davis","age":27,"email":"[email protected]"}^|^422
7^|^{"name":"Eva Green","age":29,"email":"[email protected]"}^|^400
8^|^{"name":"Frank Miller","age":34,"email":"[email protected]"}^|^404
9^|^{"name":"Grace Lee","age":31,"email":"[email protected]"}^|^422
10^|^{"name":"Henry Wilson","age":33,"email":"[email protected]"}^|^400
11 changes: 11 additions & 0 deletions src/test/java/org/springframework/RoostTest/laureatesGetTest.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
offset^|^limit^|^sort^|^ID^|^name^|^gender^|^motivation^|^affiliation^|^residence^|^birthDate^|^birthDateTo^|^deathDate^|^deathDateTo^|^foundedDate^|^birthCity^|^birthCountry^|^birthContinent^|^deathCity^|^deathCountry^|^deathContinent^|^foundedCity^|^foundedCountry^|^foundedContinent^|^HeadquartersCity^|^HeadquartersCountry^|^HeadquartersContinent^|^nobelPrizeYear^|^yearTo^|^nobelPrizeCategory^|^format^|^csvLang^|^RequestBody^|^statusCode
1^|^10^|^asc^|^1^|^John Doe^|^male^|^Scientific Research^|^Harvard University^|^Cambridge^|^1945-11-12^|^1945-11-12^|^2010-10-10^|^2010-10-10^|^1869-09-08^|^New York^|^USA^|^North America^|^Boston^|^USA^|^North America^|^Cambridge^|^USA^|^North America^|^Cambridge^|^USA^|^North America^|^1976^|^1976^|^phy^|^json^|^en^|^{"name":"John Doe","gender":"male"}^|^200
2^|^10^|^desc^|^2^|^Jane Smith^|^female^|^Peacekeeping^|^United Nations^|^New York^|^1950-05-20^|^1950-05-20^|^2015-12-12^|^2015-12-12^|^1945-10-24^|^London^|^UK^|^Europe^|^New York^|^USA^|^North America^|^New York^|^USA^|^North America^|^New York^|^USA^|^North America^|^1995^|^1995^|^pea^|^csv^|^se^|^{"name":"Jane Smith","gender":"female"}^|^200
3^|^10^|^asc^|^3^|^Bob Williams^|^male^|^Medical Research^|^Johns Hopkins University^|^Baltimore^|^1955-06-30^|^1955-06-30^|^2020-01-01^|^2020-01-01^|^1876-01-22^|^Chicago^|^USA^|^North America^|^Baltimore^|^USA^|^North America^|^Baltimore^|^USA^|^North America^|^Baltimore^|^USA^|^North America^|^2000^|^2000^|^med^|^json^|^no^|^{"name":"Bob Williams","gender":"male"}^|^200
4^|^10^|^desc^|^4^|^Alice Johnson^|^female^|^Literary Works^|^Oxford University^|^Oxford^|^1960-07-15^|^1960-07-15^|^2025-02-02^|^2025-02-02^|^1096-01-01^|^Sydney^|^Australia^|^Oceania^|^Oxford^|^UK^|^Europe^|^Oxford^|^UK^|^Europe^|^Oxford^|^UK^|^Europe^|^2010^|^2010^|^lit^|^csv^|^en^|^{"name":"Alice Johnson","gender":"female"}^|^200
5^|^10^|^asc^|^5^|^Charlie Brown^|^male^|^Economic Theory^|^Stanford University^|^Stanford^|^1965-08-01^|^1965-08-01^|^2030-03-03^|^2030-03-03^|^1885-10-01^|^Toronto^|^Canada^|^North America^|^Stanford^|^USA^|^North America^|^Stanford^|^USA^|^North America^|^Stanford^|^USA^|^North America^|^2015^|^2015^|^eco^|^json^|^se^|^{"name":"Charlie Brown","gender":"male"}^|^200
6^|^10^|^desc^|^6^|^Emily Davis^|^female^|^Chemical Research^|^MIT^|^Cambridge^|^1970-09-10^|^1970-09-10^|^2035-04-04^|^2035-04-04^|^1861-04-10^|^Beijing^|^China^|^Asia^|^Cambridge^|^USA^|^North America^|^Cambridge^|^USA^|^North America^|^Cambridge^|^USA^|^North America^|^2020^|^2020^|^che^|^csv^|^no^|^{"name":"Emily Davis","gender":"female"}^|^200
7^|^10^|^asc^|^7^|^David Wilson^|^male^|^Physics Research^|^Princeton University^|^Princeton^|^1975-10-20^|^1975-10-20^|^2040-05-05^|^2040-05-05^|^1746-10-22^|^Mumbai^|^India^|^Asia^|^Princeton^|^USA^|^North America^|^Princeton^|^USA^|^North America^|^Princeton^|^USA^|^North America^|^2025^|^2025^|^phy^|^json^|^en^|^{"name":"David Wilson","gender":"male"}^|^200
8^|^10^|^desc^|^8^|^Sophia Martinez^|^female^|^Peacekeeping^|^UNESCO^|^Paris^|^1980-11-30^|^1980-11-30^|^2045-06-06^|^2045-06-06^|^1945-11-16^|^Rio de Janeiro^|^Brazil^|^South America^|^Paris^|^France^|^Europe^|^Paris^|^France^|^Europe^|^Paris^|^France^|^Europe^|^2030^|^2030^|^pea^|^csv^|^se^|^{"name":"Sophia Martinez","gender":"female"}^|^200
9^|^10^|^asc^|^9^|^James Thomas^|^male^|^Medical Research^|^Yale University^|^New Haven^|^1985-12-15^|^1985-12-15^|^2050-07-07^|^2050-07-07^|^1701-10-09^|^Moscow^|^Russia^|^Europe^|^New Haven^|^USA^|^North America^|^New Haven^|^USA^|^North America^|^New Haven^|^USA^|^North America^|^2035^|^2035^|^med^|^json^|^no^|^{"name":"James Thomas","gender":"male"}^|^200
10^|^10^|^desc^|^10^|^Isabella Jackson^|^female^|^Literary Works^|^Cambridge University^|^Cambridge^|^1990-01-01^|^1990-01-01^|^2055-08-08^|^2055-08-08^|^1209-01-01^|^Cairo^|^Egypt^|^Africa^|^Cambridge^|^UK^|^Europe^|^Cambridge^|^UK^|^Europe^|^Cambridge^|^UK^|^Europe^|^2040^|^2040^|^lit^|^csv^|^en^|^{"name":"Isabella Jackson","gender":"female"}^|^200
Loading