RestAssured是基于Java的领域特定语言,专为简化RESTful API测试而设计。架构围绕流畅接口模式构建,将HTTP请求构造、响应提取和断言验证集成到统一链式调用中。
测试框架采用分层设计:底层HTTP客户端处理网络通信,中间层提供DSL语法糖,上层集成测试运行和报告生成。这种架构支持从简单端点验证到复杂业务流程的全场景覆盖。
环境配置与项目初始化
Maven依赖配置
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>5.3.0</version> <scope>test</scope></dependency><dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.8.0</version> <scope>test</scope></dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version></dependency>
基础测试类配置
public class ApiTestBase {
@BeforeClass
public void setup() {
RestAssured.baseURI = "https://api.example.com";
RestAssured.port = 443;
RestAssured.basePath = "/v1"; // 统一请求配置
RestAssured.requestSpecification = new RequestSpecBuilder()
.setContentType(ContentType.JSON)
.setAccept(ContentType.JSON)
.addHeader("User-Agent", "Automation-Test-Suite")
.build(); // 响应日志配置
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
}}请求构造技术详解
GET请求处理
@Testpublic void testGetUserProfile() {
given()
.queryParam("fields", "name,email,created_at")
.pathParam("userId", "12345")
.auth().oauth2(accessToken)
.when()
.get("/users/{userId}")
.then()
.statusCode(200)
.time(lessThan(2000L)); // 响应时间断言
}POST请求数据构造
@Testpublic void testCreateOrder() {
Map<String, Object> orderData = new HashMap<>();
orderData.put("productId", "P1001");
orderData.put("quantity", 2);
orderData.put("shippingAddress", addressMap);
given()
.body(orderData)
.when()
.post("/orders")
.then()
.statusCode(201)
.header("Location", notNullValue())
.body("orderId", matchesPattern("[A-Z0-9]{10}"));}文件上传测试
@Testpublic void testFileUpload() {
File documentFile = new File("test-data/contract.pdf");
given()
.multiPart("file", documentFile, "application/pdf")
.formParam("category", "legal") .when()
.post("/documents/upload")
.then()
.statusCode(200)
.body("fileId", notNullValue())
.body("fileSize", greaterThan(0));}响应验证与数据提取
JSON响应深度验证
@Testpublic void testUserResponseStructure() {
Response response = when().get("/users/123");
response.then()
.rootPath("data.attributes")
.body("firstName", equalTo("John"))
.body("lastName", equalTo("Doe"))
.body("age", allOf(greaterThan(18), lessThan(100)))
.body("emails", hasSize(2))
.body("emails[0].type", equalTo("primary"))
.body("addresses.find { it.type == 'billing' }.city", equalTo("New York"));}XML响应处理
@Testpublic void testXmlResponse() {
when()
.get("/catalog/products/123")
.then()
.statusCode(200)
.contentType(ContentType.XML)
.body("product.@id", equalTo("123"))
.body("product.name", equalTo("Test Product"))
.body("product.categories.category.size()", greaterThan(0));}响应数据提取与复用
@Testpublic void testMultiStepWorkflow() { // 第一步:创建资源
String resourceId =
given().body(creationData)
.when().post("/resources")
.then().statusCode(201)
.extract().path("id"); // 第二步:使用上一步创建的ID
given().pathParam("id", resourceId)
.when().get("/resources/{id}")
.then().statusCode(200)
.body("status", equalTo("active"));}认证与安全测试
OAuth 2.0集成
public class OAuthTest {
private String getAccessToken() {
return given()
.auth().preemptive().basic(clientId, clientSecret)
.param("grant_type", "client_credentials")
.when().post("/oauth/token")
.then().statusCode(200)
.extract().path("access_token"); }
@Test public void testProtectedEndpoint() {
given()
.auth().oauth2(getAccessToken())
.when()
.get("/protected/data")
.then()
.statusCode(200);
}}API密钥认证
@Testpublic void testApiKeyAuthentication() {
given()
.header("X-API-Key", apiKey)
.header("X-API-Secret", apiSecret)
.when()
.get("/sensitive/data")
.then()
.statusCode(200)
.body("securityLevel", equalTo("high"));}高级测试实践
数据驱动测试
@DataProvider(name = "userScenarios")public Object[][] provideUserData() {
return new Object[][] {
{"admin", "full_access", 200},
{"user", "read_only", 200},
{"guest", "no_access", 403}
};}@Test(dataProvider = "userScenarios")public void testRoleBasedAccess(String role, String expectedPermission, int expectedStatus) {
given()
.header("X-User-Role", role)
.when()
.get("/api/data")
.then()
.statusCode(expectedStatus)
.body("permission", equalTo(expectedPermission));}请求/响应日志记录
@Testpublic void testWithDetailedLogging() {
given()
.filter(new RequestLoggingFilter()) // 记录请求详情
.filter(new ResponseLoggingFilter()) // 记录响应详情
.filter(new ErrorLoggingFilter()) // 仅错误时记录
.when()
.get("/debug/endpoint")
.then()
.statusCode(200);}JSON Schema验证
@Testpublic void testResponseSchema() {
String userSchema = "{\n" +
" \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" +
" \"type\": \"object\",\n" + " \"properties\": {\n" +
" \"id\": {\"type\": \"integer\"},\n" +
" \"email\": {\"type\": \"string\", \"format\": \"email\"}\n" +
" },\n" + " \"required\": [\"id\", \"email\"]\n" +
"}";
when()
.get("/users/1")
.then()
.statusCode(200)
.body(matchesJsonSchema(userSchema));}测试套件集成
测试生命周期管理
public class OrderWorkflowTest extends ApiTestBase {
private static String orderId;
@Test(priority = 1)
public void createOrder() {
orderId = given().body(orderData)
.when().post("/orders")
.then().statusCode(201)
.extract().path("orderId"); }
@Test(priority = 2, dependsOnMethods = "createOrder")
public void verifyOrderCreated() {
given().pathParam("orderId", orderId)
.when().get("/orders/{orderId}")
.then().statusCode(200)
.body("status", equalTo("pending"));
}
@Test(priority = 3, dependsOnMethods = "verifyOrderCreated")
public void cancelOrder() {
given().pathParam("orderId", orderId)
.when().delete("/orders/{orderId}")
.then().statusCode(204);
}}性能与稳定性测试集成
@Testpublic void testResponseTimeUnderLoad() {
given()
.when()
.get("/high-traffic/endpoint")
.then()
.time(lessThan(500L)) // 单请求响应时间
.and()
.body("processingTime", lessThan(100L)); // 业务逻辑处理时间}RestAssured框架将HTTP测试复杂性封装在简洁DSL之后,支持从基础验证到复杂工作流的全范围测试需求。其与Testing、JUnit等测试框架的无缝集成,以及与Maven/Gradle构建工具的兼容性,使其成为企业级API自动化测试的优选工具。