🧪 接口自动化测试实践分享:基于 TestNG + Allure + HttpClient
一、背景介绍
在日常接口开发过程中,后端接口的验证往往依赖前端页面或 Postman 等工具。为了实现自动化回归、减少人工测试成本,我基于 Java 生态,选用了以下技术栈构建自动化测试框架:
- TestNG:测试用例执行框架
- Allure:生成结构化、可视化的测试报告
- Apache HttpClient:发送 HTTP 请求
- Jackson:处理 JSON 格式的数据
- 外部 JSON 文件:进行测试数据驱动
二、项目结构
src
├── main
│ └── java
│ └── com.mycompany.mall.utils
│ └── HttpClientUtil.java // HTTP 请求封装
├── test
│ └── java
│ └── com.mycompany.mall.api
│ └── LoginTest.java // 登录接口测试
│ └── TestBase.java // 公共工具类
│ └── resources
│ └── test-data
│ └── login.json // 登录测试数据
三、关键实现
1. 登录测试类:LoginTest.java
@Listeners(AllureTestNg.class)
public class LoginTest extends TestBase {
// 使用 Jackson 对象处理 JSON
private ObjectMapper objectMapper = new ObjectMapper();
@Description("正常登录")
@Step("输入:有效的用户名和密码 预期:登录成功,返回 token")
@Test
public void testLoginSuccess() throws Exception {
JsonNode testData = getTestData("test-data/login.json", "testUser");
String json = objectMapper.writeValueAsString(testData);
String response = HttpClientUtil.postJson("http://localhost:8080/admin/login", json);
JsonNode respJson = objectMapper.readTree(response);
Assert.assertTrue(respJson.has("data") && respJson.get("data").has("token"), "响应体中未找到 token");
}
@Description("用户名不存在")
@Step("输入:无效的用户名 预期:登录失败,提示错误信息")
@Test
public void testLoginFailure() throws Exception {
JsonNode testData = getTestData("test-data/login.json", "testUserFailure");
String json = objectMapper.writeValueAsString(testData);
String response = HttpClientUtil.postJson("http://localhost:8080/admin/login", json);
Assert.assertTrue(response.contains("用户名或密码错误"), "未匹配到错误提示信息");
}
}
2. HTTP 请求工具类:HttpClientUtil.java
public class HttpClientUtil {
private static final CloseableHttpClient client = HttpClients.createDefault();
public static String postJson(String url, String json) throws Exception {
HttpPost post = new HttpPost(url);
post.setHeader("Content-type", "application/json");
post.setEntity(new StringEntity(json, "UTF-8"));
HttpResponse response = client.execute(post);
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
throw new RuntimeException("请求失败,状态码:" + statusCode + ",响应体:" + result);
}
return result;
}
}
3. 测试数据文件:login.json
{
"testUser": {
"username": "admin",
"password": "admin123"
},
"testUserFailure": {
"username": "wrong_user",
"password": "wrong_pass"
}
}
4. 数据读取工具方法(位于 TestBase.java
)
protected JsonNode getTestData(String path, String key) throws IOException {
InputStream is = new FileInputStream(path);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(is);
return root.get(key);
}
四、测试执行与报告查看
执行测试命令:
mvn clean test
生成 Allure 报告:
allure generate target/allure-results -o target/allure-report --clean
allure open target/allure-report
五、最佳实践建议
项目 | 建议 |
---|---|
请求封装 | 建议将 HTTP 请求逻辑抽取封装,提升复用性 |
数据驱动 | 使用 JSON 管理测试数据,便于维护和拓展 |
报告质量 | 善用 @Description 、@Step 、@Story 丰富测试报告内容 |
错误断言 | 断言尽量详细,包含失败提示,便于排查问题 |
日志打印 | 推荐打印请求体、响应体,方便排查问题 |
六、后续计划
- 支持 token 自动提取和复用
- 提供注册、登出、修改密码等完整用例
- 集成到 CI/CD 流程中(如 GitLab CI、Jenkins)
- 接口断言支持 JsonPath、Schema 校验
如果你有更多想法或建议,欢迎交流 🙌
需要我帮你转成 Markdown 格式、Word 文档或者 Notion 页面内容吗?