本文目录导读:

我将为您提供一套完整的Java接口测试案例,包含代码示例和使用说明。
项目结构
interface-test/
├── pom.xml
├── src/
│ └── test/
│ └── java/
│ ├── base/
│ │ └── BaseTest.java
│ ├── config/
│ │ └── TestConfig.java
│ ├── utils/
│ │ ├── HttpUtil.java
│ │ └── DataUtil.java
│ ├── testcases/
│ │ ├── UserApiTest.java
│ │ └── OrderApiTest.java
│ └── data/
│ └── test-data.json
核心代码实现
pom.xml 依赖配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>interface-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 测试框架 -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.0</version>
<scope>test</scope>
</dependency>
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
<!-- 数据库操作 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 接口文档 -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>
<!-- Excel数据驱动 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
基础测试类 BaseTest.java
package base;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterSuite;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BaseTest {
protected static final Logger logger = LoggerFactory.getLogger(BaseTest.class);
protected static Properties properties = new Properties();
@BeforeSuite
public void setupFramework() {
// 加载配置文件
try (InputStream input = BaseTest.class
.getClassLoader()
.getResourceAsStream("test-config.properties")) {
if (input != null) {
properties.load(input);
logger.info("配置文件加载成功");
} else {
logger.error("未找到配置文件");
}
} catch (IOException e) {
logger.error("配置文件读取失败", e);
}
}
@BeforeClass
public void setup() {
// 测试类初始化
logger.info("测试类初始化");
}
@AfterSuite
public void teardown() {
// 清理操作
logger.info("测试框架清理完成");
}
}
HTTP工具类 HttpUtil.java
package utils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.util.Map;
public class HttpUtil {
public static JSONObject sendGet(String url) {
return sendGet(url, null);
}
public static JSONObject sendGet(String url, Map<String, String> headers) {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet request = new HttpGet(url);
// 添加请求头
request.setHeader("Content-Type", "application/json");
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.setHeader(entry.getKey(), entry.getValue());
}
}
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
return JSONObject.parseObject(result);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static JSONObject sendPost(String url, JSONObject body) {
return sendPost(url, body, null);
}
public static JSONObject sendPost(String url, JSONObject body,
Map<String, String> headers) {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost request = new HttpPost(url);
request.setHeader("Content-Type", "application/json");
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.setHeader(entry.getKey(), entry.getValue());
}
}
if (body != null) {
StringEntity entity = new StringEntity(body.toString(), "UTF-8");
request.setEntity(entity);
}
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
return JSONObject.parseObject(result);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static JSONObject sendPut(String url, JSONObject body) {
return sendPut(url, body, null);
}
public static JSONObject sendPut(String url, JSONObject body,
Map<String, String> headers) {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPut request = new HttpPut(url);
request.setHeader("Content-Type", "application/json");
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.setHeader(entry.getKey(), entry.getValue());
}
}
if (body != null) {
StringEntity entity = new StringEntity(body.toString(), "UTF-8");
request.setEntity(entity);
}
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
return JSONObject.parseObject(result);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static JSONObject sendDelete(String url) {
return sendDelete(url, null);
}
public static JSONObject sendDelete(String url, Map<String, String> headers) {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpDelete request = new HttpDelete(url);
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.setHeader(entry.getKey(), entry.getValue());
}
}
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
return JSONObject.parseObject(result);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
数据工具类 DataUtil.java
package utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class DataUtil {
/**
* 从文件读取JSON数据
*/
public static JSONObject readJsonFromFile(String filePath) {
try {
String content = readFileToString(filePath);
return JSONObject.parseObject(content);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 从文件读取JSON数组数据
*/
public static JSONArray readJsonArrayFromFile(String filePath) {
try {
String content = readFileToString(filePath);
return JSONArray.parseArray(content);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将文件内容读取为字符串
*/
private static String readFileToString(String filePath) throws IOException {
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(filePath), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
content.append("\n");
}
}
return content.toString();
}
/**
* 生成随机测试数据
*/
public static String generateRandomString(int length) {
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int index = (int) (Math.random() * chars.length());
sb.append(chars.charAt(index));
}
return sb.toString();
}
/**
* 生成随机手机号
*/
public static String generateRandomPhone() {
String[] prefixes = {"138", "139", "150", "186", "188", "135", "136"};
int randomPrefix = (int) (Math.random() * prefixes.length);
StringBuilder phone = new StringBuilder(prefixes[randomPrefix]);
for (int i = 0; i < 8; i++) {
phone.append((int) (Math.random() * 10));
}
return phone.toString();
}
}
用户接口测试 UserApiTest.java
package testcases;
import base.BaseTest;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.alibaba.fastjson.JSONObject;
import utils.HttpUtil;
import utils.DataUtil;
public class UserApiTest extends BaseTest {
private final String BASE_URL = "http://localhost:8080/api";
@Test(description = "获取用户列表")
public void testGetUsers() {
JSONObject response = HttpUtil.sendGet(BASE_URL + "/users");
// 验证响应
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 200, "状态码应为200");
Assert.assertTrue(response.getBoolean("success"), "请求应该成功");
Assert.assertNotNull(response.getJSONArray("data"), "用户列表不能为空");
// 验证用户数据
JSONObject firstUser = response.getJSONArray("data").getJSONObject(0);
Assert.assertNotNull(firstUser.getString("username"), "用户名不能为空");
Assert.assertNotNull(firstUser.getString("email"), "邮箱不能为空");
logger.info("获取用户列表成功: {}", response);
}
@Test(description = "创建新用户")
public void testCreateUser() {
// 构造请求数据
String timestamp = DataUtil.generateRandomString(6);
JSONObject requestData = new JSONObject();
requestData.put("username", "test_" + timestamp);
requestData.put("email", timestamp + "@test.com");
requestData.put("password", "Test123456");
requestData.put("role", "user");
JSONObject response = HttpUtil.sendPost(BASE_URL + "/users", requestData);
// 验证响应
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 201, "创建成功状态码应为201");
JSONObject userData = response.getJSONObject("data");
Assert.assertNotNull(userData.getString("id"), "用户ID不能为空");
Assert.assertEquals(userData.getString("username"),
requestData.getString("username"), "用户名应匹配");
logger.info("创建用户成功: {}", response);
}
@Test(description = "获取用户详情")
public void testGetUserById() {
// 假设用户ID为1
JSONObject response = HttpUtil.sendGet(BASE_URL + "/users/1");
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 200);
JSONObject userData = response.getJSONObject("data");
Assert.assertEquals(userData.getInteger("id"), 1, "用户ID应为1");
Assert.assertNotNull(userData.getString("username"));
logger.info("获取用户详情成功: {}", response);
}
@Test(description = "更新用户信息")
public void testUpdateUser() {
// 构造更新数据
JSONObject requestData = new JSONObject();
requestData.put("email", "updated_test@test.com");
requestData.put("role", "admin");
JSONObject response = HttpUtil.sendPut(BASE_URL + "/users/1", requestData);
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 200);
Assert.assertTrue(response.getBoolean("success"));
logger.info("更新用户成功: {}", response);
}
@Test(description = "删除用户")
public void testDeleteUser() {
JSONObject response = HttpUtil.sendDelete(BASE_URL + "/users/2");
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 200);
Assert.assertTrue(response.getBoolean("success"));
logger.info("删除用户成功: {}", response);
}
@Test(description = "测试异常场景:创建用户缺少必要字段")
public void testCreateUserMissingRequiredField() {
JSONObject requestData = new JSONObject();
requestData.put("username", "test_user");
// 缺少email字段
JSONObject response = HttpUtil.sendPost(BASE_URL + "/users", requestData);
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"), 400, "应返回400错误");
Assert.assertEquals(response.getString("message"), "邮箱不能为空");
logger.info("异常场景测试成功: {}", response);
}
@Test(description = "测试登录接口")
public void testLogin() {
JSONObject requestData = new JSONObject();
requestData.put("username", "test_user");
requestData.put("password", "Test123456");
JSONObject response = HttpUtil.sendPost(BASE_URL + "/login", requestData);
Assert.assertNotNull(response, "响应不能为空");
Assert.assertTrue(response.getBoolean("success"));
Assert.assertNotNull(response.getString("token"), "应返回token");
logger.info("登录成功: {}", response);
}
}
数据驱动测试用例
package testcases;
import base.BaseTest;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import utils.HttpUtil;
import java.io.File;
public class DataDrivenTest extends BaseTest {
@DataProvider(name = "userData")
public Object[][] getUserData() {
// 从测试数据文件读取
String dataFile = "src/test/java/data/test-data.json";
JSONObject testData = readJsonFromFile(dataFile);
JSONArray scenarios = testData.getJSONArray("testCases");
Object[][] data = new Object[scenarios.size()][2];
for (int i = 0; i < scenarios.size(); i++) {
JSONObject scenario = scenarios.getJSONObject(i);
data[i][0] = scenario.getJSONObject("request");
data[i][1] = scenario.getJSONObject("expectedResponse");
}
return data;
}
@Test(dataProvider = "userData", description = "数据驱动测试")
public void testUserScenario(JSONObject requestData, JSONObject expectedResponse) {
String url = "http://localhost:8080/api/users";
JSONObject response = HttpUtil.sendPost(url, requestData);
Assert.assertNotNull(response, "响应不能为空");
Assert.assertEquals(response.getInteger("code"),
expectedResponse.getInteger("code"),
"状态码验证");
// 验证其他字段
if (expectedResponse.containsKey("message")) {
Assert.assertEquals(response.getString("message"),
expectedResponse.getString("message"),
"错误信息验证");
}
}
@DataProvider(name = "elderlyUsers")
public Object[][] getElderlyUsers() {
return new Object[][]{
{80, "老年客户"},
{65, "即将退休"},
{60, "中年客户"}
};
}
// 读取JSON文件的方法
private JSONObject readJsonFromFile(String filePath) {
try {
String content = new String(
java.nio.file.Files.readAllBytes(
new File(filePath).toPath()
), "UTF-8"
);
return JSONObject.parseObject(content);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
testng.xml 配置文件
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="接口测试套件" verbose="1">
<test name="用户接口测试">
<classes>
<class name="testcases.UserApiTest">
<!-- 自定义测试组 -->
<methods>
<include name="testCreateUser"></include>
<include name="testGetUsers"></include>
<include name="testUpdateUser"></include>
<include name="testDeleteUser"></include>
</methods>
</class>
</classes>
</test>
<test name="数据驱动测试">
<classes>
<class name="testcases.DataDrivenTest"></class>
</classes>
</test>
</suite>
properties 配置文件
# 测试环境配置 test.base.url=http://localhost:8080 test.username=admin test.password=admin123 # 数据库配置 db.host=localhost db.port=3306 db.username=root db.password=root123 db.database=test_db # 超时配置 http.timeout=30 </properties>
最佳实践建议
测试数据管理
// 使用外部文件管理测试数据
public class TestDataManager {
public static JSONObject getTestData(String testCaseName) {
// 从数据库或Excel文件读取测试数据
String dataFile = "test-data/" + testCaseName + ".json";
return DataUtil.readJsonFromFile(dataFile);
}
}
断言封装
public class AssertUtil {
public static void assertSuccess(JSONObject response) {
Assert.assertNotNull(response, "响应不能为空");
Assert.assertTrue(response.getBoolean("success"), "请求应该成功");
Assert.assertEquals(response.getInteger("code"), 200);
}
public static void assertBusinessException(JSONObject response) {
Assert.assertNotNull(response, "响应不能为空");
Assert.assertFalse(response.getBoolean("success"), "请求应该失败");
Assert.assertNotEquals(response.getInteger("code"), 200);
}
}
性能测试配置
// 集成JMeter或性能测试工具
public class PerformanceTest {
@Test(invocationCount = 100, threadPoolSize = 10)
public void testCreateUserConcurrent() {
// 并发测试代码
}
}
运行测试
# 运行所有测试 mvn clean test # 运行指定测试类 mvn test -Dtest=UserApiTest # 运行指定测试方法 mvn test -Dtest=UserApiTest#testCreateUser # 生成测试报告 mvn site
这个完整的接口测试框架包含了:
- 完整的HTTP请求封装(GET/POST/PUT/DELETE)
- 数据驱动测试
- 测试数据管理
- 配置文件管理
- 详细的测试用例示例
- 异常场景处理
- 日志记录
您可以根据项目的具体需求进行调整和扩展。