Java接口测试案例

wen java案例 1

本文目录导读:

Java接口测试案例

  1. 项目结构
  2. 核心代码实现
  3. 最佳实践建议
  4. 运行测试

我将为您提供一套完整的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)
  • 数据驱动测试
  • 测试数据管理
  • 配置文件管理
  • 详细的测试用例示例
  • 异常场景处理
  • 日志记录

您可以根据项目的具体需求进行调整和扩展。

上一篇REST Assured案例

下一篇JaCoCo案例

抱歉,评论功能暂时关闭!