RESTest
RESTest: Automated Black-Box Testing of RESTful Web APIs
Install / Use
/learn @isa-group/RESTestREADME
RESTest is a framework for automated black-box testing of RESTful web APIs. It follows a model-based approach, where test cases are automatically derived from the OpenAPI Specification (OAS) of the API under test. No access to the source code is required, which makes it possible to test APIs written in any programming language, running in local or remote servers.
Index
RESTest Wiki
In this page you can find a brief description of how RESTest works and an illustrating example. If you want to read the full documentation, please visit the Wiki.
Quick examples:
Using the system programmatically
Generating test cases
In this example, we illustrate how to generate a set of test cases using the Constraint-Based test case generator and write them to a file using the RESTAssured writer. Test cases are generated by randomly selecting values for each input parameter, ensuring that dependencies between parameters are met (or intentionally violated). This is made possible through the use of a constraint solver (Choco) and IDL, a domain-specific language for specifying dependencies between parameters as part of the OAS specification.
The complete code of the example is provided above.
public class Ex3_CBTGeneration {
public static String propertyFilePath="src/main/resources/Examples/Ex3_CBTGeneration/user_config.properties"; // Path to user properties file with configuration options
public static void main(String[] args) throws RESTestException {
// Load properties
RESTestLoader loader = new RESTestLoader(propertyFilePath);
// Create test case generator
ConstraintBasedTestCaseGenerator generator = (ConstraintBasedTestCaseGenerator) loader.createGenerator();
Collection<TestCase> testCases = generator.generate();
// Create target directory for test cases if it does not exist
createDir(loader.getTargetDirJava());
// Write (RestAssured) test cases
RESTAssuredWriter writer = (RESTAssuredWriter) loader.createWriter();
writer.write(testCases);
System.out.println(testCases.size() + " test cases generated and written to " + loader.getTargetDirJava());
}
}
This code demonstrates how to load the properties, create a constraint-based test case generator, generate test cases, and write them using the RESTAssured writer. Now, let's examine one of the test cases generated using RESTAssured.
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.Test;
import static org.junit.Assert.fail;
public class Ex3_CBTGeneration {
// ... Previous code ...
@Test
public void test_qec4n4cuyvcj_getMultiHotelOffers() {
String testResultId = "test_qec4n4cuyvcj_getMultiHotelOffers";
// Filter settings for specific test case
nominalOrFaultyTestCaseFilter.updateFaultyData(true, true, "individual_parameter_constraint:Violated 'min' constraint of integer parameter radius");
statusCode5XXFilter.updateFaultyData(true, true, "individual_parameter_constraint:Violated 'min' constraint of integer parameter radius");
csvFilter.setTestResultId(testResultId);
statusCode5XXFilter.setTestResultId(testResultId);
nominalOrFaultyTestCaseFilter.setTestResultId(testResultId);
validationFilter.setTestResultId(testResultId);
try {
// Build and send request using RestAssured
Response response = RestAssured
.given()
.queryParam("page[limit]", "25")
.queryParam("amenities", "BABY-SITTING,AIR_CONDITIONING")
.queryParam("hotelIds", "HSFELAAF")
.queryParam("roomQuantity", "5")
.queryParam("chains", "WV,EC,WW")
.queryParam("includeClosed", "false")
.queryParam("radius", "-3")
.queryParam("radiusUnit", "MILE")
.queryParam("checkInDate", "2023-11-14")
.queryParam("rateCodes", "WKD,STP,TUR")
.queryParam("paymentPolicy", "DEPOSIT")
.filter(allureFilter)
.filter(statusCode5XXFilter)
.filter(nominalOrFaultyTestCaseFilter)
.filter(validationFilter)
.filter(csvFilter)
.when()
.get("/shopping/hotel-offers");
// Verify the response
response.then();
System.out.println("El caso de prueba pasó exitosamente.");
} catch (RuntimeException ex) {
System.err.println(ex.getMessage());
fail(ex.getMessage());
}
}
}
Running test cases
This example will illustrate how to execute a set of tests that have been previously generated using ResTestExecutor. Below is an example of how this process would be carried out.
public class Ex8_TestExecution {
public static final String PROPERTY_FILE_PATH = "src/main/resources/Examples/Ex8_TestExecution/user_config.properties"; // Path to user properties file with configuration options
public static void main(String[] args) throws RESTestException {
// Execute tests
RESTestExecutor executor = new RESTestExecutor(PROPERTY_FILE_PATH);
executor.execute();
}
}
Generating and running test cases
In this example, we will explore the generation and execution of test cases using RESTestRunner, a tool that enables the creation of an automated workflow to manage the entire testing process. Below is an example illustrating how this workflow would be executed.
public class Ex9_Generation_Execution {
public static final String PROPERTY_FILE_PATH = "src/main/resources/Examples/Ex9_Generation_Execution/user_config.properties"; // Path to user properties file with configuration options
public static final Logger logger = Logger.getLogger(Ex9_Generation_Execution.class.getName());
public static void main(String[] args) throws RESTestException {
// Load properties
RESTestRunner runner = new RESTestRunner(PROPERTY_FILE_PATH);
// Run workflow
runner.run();
if (logger.isLoggable(java.util.logging.Level.INFO)) {
String message1 = String.format("%d test cases generated and written to %s", runner.getNumberOfTestCases(), runner.getTargetDirJava());
String message2 = String.format("Allure report available at %s", runner.getAllureReportsPath());
String message3 = String.format("CSV stats available at %s/%s", PropertyManager.readProperty("data.tests.dir")
