本文目录导读:

我来为您提供几个REST Assured的实战案例,从基础到高级应用。
基础GET请求测试
简单GET请求
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class BasicGETTests {
@Test
public void testGetSingleUser() {
// 设置基础URL
RestAssured.baseURI = "https://api.example.com";
// 发送GET请求并验证响应
given()
.header("Content-Type", "application/json")
.when()
.get("/users/1")
.then()
.statusCode(200)
.body("id", equalTo(1))
.body("name", equalTo("John Doe"))
.body("email", containsString("@example.com"));
}
@Test
public void testGetAllUsers() {
given()
.queryParam("page", 1)
.queryParam("limit", 10)
.when()
.get("/users")
.then()
.statusCode(200)
.body("data.size()", greaterThan(0))
.body("total", greaterThan(0));
}
}
POST请求创建资源
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.Map;
public class POSTRequestsTests {
@Test
public void testCreateUser() {
// 使用Map创建请求体
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("name", "Jane Smith");
requestBody.put("email", "jane@example.com");
requestBody.put("age", 28);
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/users")
.then()
.statusCode(201)
.body("id", notNullValue())
.body("name", equalTo("Jane Smith"));
}
@Test
public void testCreateUserWithPojo() {
// 使用POJO对象
User user = new User();
user.setName("Bob Johnson");
user.setEmail("bob@example.com");
user.setAge(32);
given()
.contentType(ContentType.JSON)
.body(user)
.when()
.post("/users")
.then()
.statusCode(201)
.body("name", equalTo("Bob Johnson"));
}
// POJO类
static class User {
private String name;
private String email;
private int age;
// getters和setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
}
PUT/PATCH/DELETE操作
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
public class UpdateDeleteTests {
@Test
public void testUpdateUser() {
String updateBody = """
{
"name": "Updated Name",
"email": "updated@example.com"
}
""";
given()
.contentType(ContentType.JSON)
.body(updateBody)
.when()
.put("/users/1")
.then()
.statusCode(200)
.body("name", equalTo("Updated Name"));
}
@Test
public void testPartialUpdateUser() {
String patchBody = """
{
"age": 30
}
""";
given()
.contentType(ContentType.JSON)
.body(patchBody)
.when()
.patch("/users/1")
.then()
.statusCode(200)
.body("age", equalTo(30));
}
@Test
public void testDeleteUser() {
given()
.pathParam("id", 1)
.when()
.delete("/users/{id}")
.then()
.statusCode(204); // 204 No Content
}
}
高级响应验证
import io.restassured.response.Response;
import org.testng.annotations.Test;
import java.util.List;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ResponseValidationTests {
@Test
public void testResponseHeaders() {
given()
.when()
.get("/users/1")
.then()
.statusCode(200)
.header("Content-Type", containsString("application/json"))
.header("Server", equalTo("nginx"))
.time(lessThan(2000L)); // 响应时间小于2秒
}
@Test
public void testComplexNestedJson() {
Response response = given()
.when()
.get("/users/1/posts")
.then()
.statusCode(200)
.extract()
.response();
// 提取数据
String userName = response.jsonPath().getString("author.name");
List<String> titles = response.jsonPath().getList("posts.title");
int postCount = response.jsonPath().getInt("posts.size()");
// 验证嵌套结构
given()
.when()
.get("/users/1/posts")
.then()
.body("author.name", equalTo("John Doe"))
.body("posts[0].title", containsString("First"))
.body("posts.findAll { it.likes > 100 }.size()", greaterThan(0));
}
@Test
public void testMultipleAssertions() {
given()
.when()
.get("/users")
.then()
.statusCode(200)
.assertThat()
.body("data.name", hasItems("Alice", "Bob"))
.body("data.findAll { it.age > 25 }.age", everyItem(greaterThan(25)))
.body("total_pages", allOf(greaterThan(0), lessThan(10)));
}
@Test
public void testXmlResponse() {
given()
.accept("application/xml")
.when()
.get("/users/1")
.then()
.statusCode(200)
.body("user.name", equalTo("John Doe"))
.body("user.address.city", equalTo("New York"));
}
}
认证和Token处理
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
public class AuthTests {
private static String authToken;
@BeforeClass
public void setup() {
// 获取认证Token
String loginBody = """
{
"username": "testuser",
"password": "testpass"
}
""";
authToken = given()
.contentType(ContentType.JSON)
.body(loginBody)
.when()
.post("/auth/login")
.then()
.statusCode(200)
.extract()
.path("token");
}
@Test
public void testWithBearerToken() {
given()
.header("Authorization", "Bearer " + authToken)
.when()
.get("/protected/resource")
.then()
.statusCode(200);
}
@Test
public void testWithBasicAuth() {
given()
.auth()
.basic("username", "password")
.when()
.get("/basic-auth-endpoint")
.then()
.statusCode(200);
}
@Test
public void testWithOAuth2() {
// 简化示例,实际需要更复杂的OAuth2流程
given()
.auth()
.oauth2(authToken)
.when()
.get("/oauth2/endpoint")
.then()
.statusCode(200);
}
}
完整测试框架示例
import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class CompleteTestFramework {
private static RequestSpecification requestSpec;
private static ResponseSpecification responseSpec;
@BeforeClass
public void setup() {
// 配置请求规范
requestSpec = new RequestSpecBuilder()
.setBaseUri("https://api.example.com")
.setContentType(ContentType.JSON)
.addHeader("X-API-Key", "your-api-key")
.build();
// 配置响应规范
responseSpec = new ResponseSpecBuilder()
.expectStatusCode(200)
.expectContentType(ContentType.JSON)
.expectResponseTime(lessThan(3000L))
.build();
// 全局设置
RestAssured.requestSpecification = requestSpec;
RestAssured.responseSpecification = responseSpec;
}
@Test
public void completeUserFlow() {
// 1. 创建用户
String userId = given()
.body("""
{
"name": "Test User",
"email": "test@example.com",
"password": "password123"
}
""")
.when()
.post("/users")
.then()
.statusCode(201)
.extract()
.path("id");
// 2. 获取用户信息
given()
.pathParam("id", userId)
.when()
.get("/users/{id}")
.then()
.spec(responseSpec)
.body("id", equalTo(userId))
.body("name", equalTo("Test User"));
// 3. 更新用户信息
given()
.pathParam("id", userId)
.body("""
{
"name": "Updated Name"
}
""")
.when()
.patch("/users/{id}")
.then()
.statusCode(200)
.body("name", equalTo("Updated Name"));
// 4. 删除用户
given()
.pathParam("id", userId)
.when()
.delete("/users/{id}")
.then()
.statusCode(204);
}
}
文件上传和下载
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import java.io.File;
public class FileHandlingTests {
@Test
public void testFileUpload() {
given()
.multiPart("file", new File("/path/to/file.pdf"))
.multiPart("description", "Test document")
.when()
.post("/upload")
.then()
.statusCode(200)
.body("success", equalTo(true));
}
@Test
public void testFileDownload() {
byte[] fileContent = given()
.when()
.get("/download/report.pdf")
.then()
.statusCode(200)
.extract()
.asByteArray();
// 保存到文件
try {
java.nio.file.Files.write(
java.nio.file.Paths.get("report.pdf"),
fileContent
);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testUploadMultipleFiles() {
given()
.multiPart("files[]", new File("/path/to/file1.txt"))
.multiPart("files[]", new File("/path/to/file2.txt"))
.multiPart("metadata", """
{
"category": "documents",
"description": "Test files"
}
""")
.when()
.post("/multi-upload")
.then()
.statusCode(200)
.body("uploaded_count", equalTo(2));
}
}
日志和调试
import org.testng.annotations.Test;
public class LoggingTests {
@Test
public void testWithLogging() {
given()
.log().all() // 记录所有请求信息
.when()
.get("/users/1")
.then()
.log().all() // 记录所有响应信息
.statusCode(200);
}
@Test
public void testSelectiveLogging() {
given()
.log().method()
.log().uri()
.log().headers()
.log().body()
.when()
.get("/users/1")
.then()
.log().status()
.log().headers()
.statusCode(200);
}
@Test
public void testLogOnFailure() {
given()
.when()
.get("/invalid-endpoint")
.then()
.log().ifValidationFails() // 只在失败时记录
.statusCode(404);
}
}
并行测试和性能优化
import org.testng.annotations.Test;
import java.util.concurrent.CompletableFuture;
public class ParallelTests {
@Test
public void testParallelRequests() {
// 并发请求示例
CompletableFuture.allOf(
CompletableFuture.runAsync(() -> {
given().when().get("/users/1").then().statusCode(200);
}),
CompletableFuture.runAsync(() -> {
given().when().get("/users/2").then().statusCode(200);
}),
CompletableFuture.runAsync(() -> {
given().when().get("/users/3").then().statusCode(200);
})
).join();
}
@Test(invocationCount = 5, threadPoolSize = 5)
public void testRepeatedRequests() {
given()
.when()
.get("/test-endpoint")
.then()
.statusCode(200);
}
}
数据驱动测试
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataDrivenTests {
@DataProvider(name = "userData")
public Object[][] userData() {
return new Object[][] {
{"Alice", 25, true},
{"Bob", 30, true},
{"Charlie", 17, false}, // 未成年人
{"David", 35, true}
};
}
@Test(dataProvider = "userData")
public void testUserValidation(String name, int age, boolean expectedValid) {
String userBody = String.format(
"{\"name\":\"%s\",\"age\":%d}", name, age
);
given()
.contentType(ContentType.JSON)
.body(userBody)
.when()
.post("/validate-user")
.then()
.statusCode(200)
.body("valid", equalTo(expectedValid));
}
@DataProvider(name = "postsData")
public Object[][] postsData() {
return new Object[][] {
{1, "Post 1"},
{2, "Post 2"},
{3, "Post 3"}
};
}
@Test(dataProvider = "postsData")
public void testMultiplePosts(int postId, String expectedTitle) {
given()
.pathParam("id", postId)
.when()
.get("/posts/{id}")
.then()
.statusCode(200)
.body("title", equalTo(expectedTitle));
}
}
这些示例涵盖了REST Assured的主要功能,要运行这些测试,您需要:
-
在pom.xml中添加依赖:
<dependencies> <!-- REST Assured --> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>5.4.0</version> <scope>test</scope> </dependency> <!-- TestNG --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.8.0</version> <scope>test</scope> </dependency> <!-- JSON 解析 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.16.1</version> </dependency> </dependencies>
这些案例涵盖了REST API测试的常见场景,您可以根据实际需求进行调整和扩展。