AI自动化测试平台技术方案
一、方案概述
基于现有的Spring Boot 3 + AI集成架构,构建一个AI辅助的软件自动化测试平台。通过AI生成测试用例,自动执行并分析结果,提升测试效率。
二、架构设计
2.1 总体架构
┌─────────────────────────────────────────────────────────────┐
│ AI自动化测试平台 │
├─────────────────────────────────────────────────────────────┤
│ 用户交互层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 项目管理 │ │ 用例管理 │ │ 报告查看 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 业务逻辑层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ AI用例生成 │ │ 测试执行引擎 │ │ 结果分析 │ │
│ │ - Prompt管理 │ │ - 任务调度 │ │ - AI分析 │ │
│ │ - 多模型支持 │ │ - 并发执行 │ │ - 报告生成 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 测试执行层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ API测试 │ │ UI测试 │ │ 性能测试 │ │
│ │ RestAssured │ │ Playwright │ │ JMeter │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 数据持久层 │
│ ┌──────────────────────────────────────────────────┐ │
│ │ PostgreSQL + MyBatis-Flex │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘2.2 核心技术栈
| 层次 | 技术选型 | 说明 |
|---|---|---|
| 后端框架 | Spring Boot 3.x | 复用现有架构 |
| ORM | MyBatis-Flex | 现有数据访问层 |
| AI集成 | beyondsoft-ai-spring3-starter | 复用现有多AI平台集成 |
| API测试 | REST Assured 5.x | Java生态最佳实践 |
| UI测试 | Playwright for Java | 现代化、快速、跨浏览器 |
| 性能测试 | JMeter (可选) | 业界标准 |
| 测试报告 | Allure 2.x | 美观的测试报告 |
| 异步任务 | Spring @Async + CompletableFuture | 并发执行支持 |
| 数据库 | PostgreSQL | 现有数据库 |
三、数据库设计
3.1 核心表结构
sql
-- 测试项目表
CREATE TABLE test_project (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
description TEXT,
base_url VARCHAR(500) NOT NULL COMMENT '测试目标地址',
test_type VARCHAR(50) DEFAULT 'API' COMMENT 'API/UI/PERFORMANCE',
headers JSONB COMMENT '公共请求头',
auth_config JSONB COMMENT '认证配置',
env_variables JSONB COMMENT '环境变量',
status VARCHAR(50) DEFAULT 'ACTIVE' COMMENT 'ACTIVE/ARCHIVED',
created_by VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- AI生成的测试用例表
CREATE TABLE test_case (
id BIGSERIAL PRIMARY KEY,
project_id BIGINT NOT NULL REFERENCES test_project(id),
case_name VARCHAR(200) NOT NULL,
description TEXT,
test_type VARCHAR(50) NOT NULL COMMENT 'API/UI/UNIT/PERFORMANCE',
-- AI生成信息
generated_by_ai BOOLEAN DEFAULT TRUE,
ai_provider VARCHAR(50) COMMENT '使用的AI提供商',
ai_model VARCHAR(100) COMMENT '使用的AI模型',
generation_prompt TEXT COMMENT '生成用例的提示词',
-- 用例内容 (JSONB灵活存储不同类型测试)
case_content JSONB NOT NULL COMMENT '用例详细内容',
-- API测试示例:
-- {
-- "method": "POST",
-- "endpoint": "/api/users",
-- "headers": {"Content-Type": "application/json"},
-- "body": {"name": "test", "email": "test@example.com"},
-- "assertions": [
-- {"type": "statusCode", "expected": 200},
-- {"type": "jsonPath", "path": "$.data.id", "expected": "notNull"}
-- ]
-- }
priority INTEGER DEFAULT 1 COMMENT '优先级 1-高 2-中 3-低',
tags VARCHAR(200)[] COMMENT '标签数组',
status VARCHAR(50) DEFAULT 'ACTIVE' COMMENT 'DRAFT/ACTIVE/ARCHIVED',
created_by VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 测试套件 (可选,用于批量执行)
CREATE TABLE test_suite (
id BIGSERIAL PRIMARY KEY,
project_id BIGINT NOT NULL REFERENCES test_project(id),
suite_name VARCHAR(200) NOT NULL,
description TEXT,
case_ids BIGINT[] COMMENT '包含的用例ID数组',
execution_order VARCHAR(20) DEFAULT 'SEQUENTIAL' COMMENT 'SEQUENTIAL/PARALLEL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 测试执行记录表
CREATE TABLE test_execution (
id BIGSERIAL PRIMARY KEY,
case_id BIGINT REFERENCES test_case(id),
suite_id BIGINT REFERENCES test_suite(id),
-- 执行信息
execution_time TIMESTAMP NOT NULL,
status VARCHAR(50) NOT NULL COMMENT 'SUCCESS/FAILED/ERROR/SKIPPED',
duration_ms BIGINT COMMENT '执行耗时(毫秒)',
-- 结果详情
result_detail JSONB COMMENT '详细执行结果',
-- {
-- "request": {...},
-- "response": {...},
-- "assertions": [
-- {"name": "状态码检查", "passed": true},
-- {"name": "响应时间", "passed": false, "message": "超过1000ms"}
-- ]
-- }
error_message TEXT COMMENT '错误信息',
stack_trace TEXT COMMENT '异常堆栈',
screenshots TEXT[] COMMENT 'UI测试截图路径数组',
-- 环境信息
executor VARCHAR(100) COMMENT '执行者',
execution_env VARCHAR(50) COMMENT '执行环境',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- AI分析报告表
CREATE TABLE test_analysis_report (
id BIGSERIAL PRIMARY KEY,
execution_id BIGINT REFERENCES test_execution(id),
suite_id BIGINT REFERENCES test_suite(id),
-- AI分析内容
ai_provider VARCHAR(50) COMMENT '使用的AI提供商',
ai_model VARCHAR(100) COMMENT '使用的AI模型',
analysis_content TEXT COMMENT 'AI对测试结果的分析',
failure_reasons JSONB COMMENT '失败原因分析',
suggestions JSONB COMMENT '改进建议',
risk_assessment TEXT COMMENT '风险评估',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX idx_test_case_project ON test_case(project_id);
CREATE INDEX idx_test_execution_case ON test_execution(case_id);
CREATE INDEX idx_test_execution_time ON test_execution(execution_time);
CREATE INDEX idx_test_execution_status ON test_execution(status);3.2 用例内容示例
API测试用例
json
{
"method": "POST",
"endpoint": "/api/v1/users",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ${token}"
},
"body": {
"name": "张三",
"email": "zhangsan@example.com",
"age": 25
},
"assertions": [
{
"type": "statusCode",
"expected": 201,
"description": "创建成功应返回201"
},
{
"type": "jsonPath",
"path": "$.data.id",
"expected": "notNull",
"description": "返回的用户ID不能为空"
},
{
"type": "responseTime",
"expected": 1000,
"operator": "lessThan",
"description": "响应时间小于1秒"
}
],
"setup": {
"preRequests": ["/api/v1/auth/login"],
"teardown": ["/api/v1/users/${userId}"]
}
}UI测试用例
json
{
"browser": "chromium",
"viewport": {"width": 1920, "height": 1080},
"steps": [
{
"action": "navigate",
"url": "https://example.com/login"
},
{
"action": "fill",
"selector": "#username",
"value": "testuser"
},
{
"action": "fill",
"selector": "#password",
"value": "password123"
},
{
"action": "click",
"selector": "button[type='submit']"
},
{
"action": "waitForSelector",
"selector": ".dashboard",
"timeout": 5000
},
{
"action": "screenshot",
"path": "screenshots/login-success.png"
}
],
"assertions": [
{
"type": "url",
"expected": "https://example.com/dashboard",
"description": "登录后应跳转到dashboard"
},
{
"type": "elementVisible",
"selector": ".user-avatar",
"description": "应显示用户头像"
}
]
}四、核心模块设计
4.1 AI用例生成模块
4.1.1 服务接口
java
package com.beyondsoft.framework.bussines.autotest.service;
public interface AiTestCaseGeneratorService {
/**
* 根据需求描述生成API测试用例
*/
List<TestCase> generateApiTestCases(GenerateTestCaseRequest request);
/**
* 根据OpenAPI规范生成测试用例
*/
List<TestCase> generateFromOpenApi(String openApiSpec);
/**
* 根据现有代码生成单元测试
*/
List<TestCase> generateUnitTests(String sourceCode, String className);
/**
* 优化现有测试用例
*/
TestCase optimizeTestCase(TestCase existingCase, List<ExecutionResult> historyResults);
}4.1.2 Prompt模板设计
java
package com.beyondsoft.framework.bussines.autotest.prompt;
public class TestCasePromptTemplates {
public static final String API_TEST_GENERATION = """
你是一个专业的API测试工程师。请根据以下信息生成详细的API测试用例:
## 接口信息
- 接口地址: {endpoint}
- 请求方法: {method}
- 接口描述: {description}
- 请求参数: {parameters}
- 响应示例: {responseExample}
## 要求
1. 生成至少5个测试场景(正常场景、边界场景、异常场景)
2. 每个用例包含:
- 用例名称(清晰描述测试目的)
- 请求参数(JSON格式)
- 预期断言(状态码、响应字段、业务逻辑)
3. 考虑以下测试点:
- 参数校验(必填项、格式校验、长度限制)
- 权限校验
- 业务逻辑正确性
- 并发安全性
## 输出格式
请以JSON数组格式返回,每个元素包含:
{
"caseName": "用例名称",
"description": "用例描述",
"priority": 1, // 1-高 2-中 3-低
"caseContent": {
"method": "POST",
"endpoint": "/api/xxx",
"headers": {},
"body": {},
"assertions": [
{"type": "statusCode", "expected": 200},
{"type": "jsonPath", "path": "$.data.id", "expected": "notNull"}
]
}
}
""";
public static final String TEST_RESULT_ANALYSIS = """
你是一个测试分析专家。请分析以下测试执行结果并给出专业建议:
## 执行结果
- 总用例数: {totalCases}
- 成功: {successCount}
- 失败: {failedCount}
- 失败用例详情: {failureDetails}
## 请提供
1. 失败原因分析(根本原因)
2. 风险评估(对业务的影响程度)
3. 修复建议(具体可行的方案)
4. 测试改进建议
请以结构化JSON格式返回。
""";
}4.2 测试执行引擎
4.2.1 执行器接口
java
package com.beyondsoft.framework.bussines.autotest.executor;
public interface TestCaseExecutor {
/**
* 执行单个测试用例
*/
ExecutionResult execute(TestCase testCase, ExecutionContext context);
/**
* 批量执行测试用例
*/
List<ExecutionResult> executeBatch(List<TestCase> testCases, ExecutionContext context);
/**
* 支持的测试类型
*/
TestType supportedType();
}4.2.2 API测试执行器实现
java
package com.beyondsoft.framework.bussines.autotest.executor.impl;
@Component
public class ApiTestExecutor implements TestCaseExecutor {
@Override
public ExecutionResult execute(TestCase testCase, ExecutionContext context) {
ExecutionResult result = new ExecutionResult();
result.setCaseId(testCase.getId());
result.setExecutionTime(LocalDateTime.now());
try {
// 1. 解析用例内容
ApiTestContent content = parseContent(testCase.getCaseContent());
// 2. 构建RestAssured请求
RequestSpecification request = RestAssured.given()
.baseUri(context.getBaseUrl())
.headers(mergeHeaders(content.getHeaders(), context.getCommonHeaders()))
.body(content.getBody());
// 3. 执行请求并记录耗时
long startTime = System.currentTimeMillis();
Response response = request.request(content.getMethod(), content.getEndpoint());
long duration = System.currentTimeMillis() - startTime;
result.setDurationMs(duration);
// 4. 执行断言
List<AssertionResult> assertionResults = new ArrayList<>();
for (Assertion assertion : content.getAssertions()) {
AssertionResult ar = executeAssertion(assertion, response);
assertionResults.add(ar);
}
// 5. 判断整体结果
boolean allPassed = assertionResults.stream().allMatch(AssertionResult::isPassed);
result.setStatus(allPassed ? ExecutionStatus.SUCCESS : ExecutionStatus.FAILED);
// 6. 记录详细结果
result.setResultDetail(buildResultDetail(response, assertionResults));
} catch (Exception e) {
result.setStatus(ExecutionStatus.ERROR);
result.setErrorMessage(e.getMessage());
result.setStackTrace(ExceptionUtils.getStackTrace(e));
}
return result;
}
private AssertionResult executeAssertion(Assertion assertion, Response response) {
AssertionResult result = new AssertionResult();
result.setName(assertion.getDescription());
try {
switch (assertion.getType()) {
case "statusCode":
int actualStatus = response.getStatusCode();
int expectedStatus = (Integer) assertion.getExpected();
result.setPassed(actualStatus == expectedStatus);
result.setMessage(String.format("状态码: 预期=%d, 实际=%d", expectedStatus, actualStatus));
break;
case "jsonPath":
String path = assertion.getPath();
Object actualValue = response.jsonPath().get(path);
Object expectedValue = assertion.getExpected();
if ("notNull".equals(expectedValue)) {
result.setPassed(actualValue != null);
} else {
result.setPassed(Objects.equals(actualValue, expectedValue));
}
result.setMessage(String.format("JsonPath=%s: 预期=%s, 实际=%s", path, expectedValue, actualValue));
break;
case "responseTime":
long responseTime = response.getTime();
long threshold = ((Number) assertion.getExpected()).longValue();
result.setPassed(responseTime < threshold);
result.setMessage(String.format("响应时间: %dms (阈值:%dms)", responseTime, threshold));
break;
default:
result.setPassed(false);
result.setMessage("不支持的断言类型: " + assertion.getType());
}
} catch (Exception e) {
result.setPassed(false);
result.setMessage("断言执行异常: " + e.getMessage());
}
return result;
}
@Override
public TestType supportedType() {
return TestType.API;
}
}4.3 测试服务层
java
package com.beyondsoft.framework.bussines.autotest.service.impl;
@Service
@Slf4j
public class TestExecutionServiceImpl implements TestExecutionService {
private final Map<TestType, TestCaseExecutor> executors;
private final AiService aiService;
private final TestCaseMapper testCaseMapper;
private final TestExecutionMapper testExecutionMapper;
public TestExecutionServiceImpl(List<TestCaseExecutor> executorList,
AiService aiService,
TestCaseMapper testCaseMapper,
TestExecutionMapper testExecutionMapper) {
this.executors = executorList.stream()
.collect(Collectors.toMap(TestCaseExecutor::supportedType, Function.identity()));
this.aiService = aiService;
this.testCaseMapper = testCaseMapper;
this.testExecutionMapper = testExecutionMapper;
}
@Override
@Async
public CompletableFuture<TestReport> executeTestSuite(TestSuiteRequest request) {
log.info("开始执行测试套件: {}", request.getSuiteId());
try {
// 1. 获取测试用例
List<TestCase> testCases = testCaseMapper.selectBySuiteId(request.getSuiteId());
// 2. 构建执行上下文
ExecutionContext context = buildContext(request);
// 3. 执行测试用例
List<ExecutionResult> results;
if (request.isParallel()) {
results = executeParallel(testCases, context);
} else {
results = executeSequential(testCases, context);
}
// 4. 保存执行记录
results.forEach(testExecutionMapper::insert);
// 5. AI分析结果
TestAnalysisReport aiAnalysis = analyzeWithAi(results);
// 6. 生成测试报告
TestReport report = buildReport(results, aiAnalysis);
log.info("测试套件执行完成: 成功={}, 失败={}",
report.getSuccessCount(), report.getFailedCount());
return CompletableFuture.completedFuture(report);
} catch (Exception e) {
log.error("测试套件执行失败", e);
return CompletableFuture.failedFuture(e);
}
}
private List<ExecutionResult> executeParallel(List<TestCase> testCases, ExecutionContext context) {
// 并行执行
return testCases.parallelStream()
.map(testCase -> {
TestCaseExecutor executor = executors.get(testCase.getTestType());
return executor.execute(testCase, context);
})
.collect(Collectors.toList());
}
private List<ExecutionResult> executeSequential(List<TestCase> testCases, ExecutionContext context) {
// 串行执行
return testCases.stream()
.map(testCase -> {
TestCaseExecutor executor = executors.get(testCase.getTestType());
return executor.execute(testCase, context);
})
.collect(Collectors.toList());
}
private TestAnalysisReport analyzeWithAi(List<ExecutionResult> results) {
// 使用AI分析测试结果
String prompt = buildAnalysisPrompt(results);
AiChatRequest chatRequest = AiChatRequest.builder()
.messages(List.of(
new AiChatRequest.ChatMessage("system", "你是一个专业的测试分析专家"),
new AiChatRequest.ChatMessage("user", prompt)
))
.build();
// 复用现有AI服务
AiChatResponse aiResponse = aiService.chat(chatRequest);
// 解析AI分析结果
return parseAnalysisResult(aiResponse.getContent());
}
}五、实施计划
Phase 1: MVP核心功能 (2-3周)
目标: 实现API自动化测试完整流程
- [ ] Week 1: 数据库设计 + 实体类生成
- [ ] Week 1-2: AI用例生成模块
- Prompt模板设计
- 集成现有AI服务
- 用例生成接口开发
- [ ] Week 2-3: 测试执行引擎
- RestAssured集成
- API测试执行器实现
- 执行结果存储
- [ ] Week 3: 基础接口开发
- 项目管理接口
- 用例管理接口
- 执行报告接口
Phase 2: AI增强 (1-2周)
- [ ] AI结果分析功能
- [ ] 基于历史数据的用例优化
- [ ] 智能断言生成
Phase 3: 高级特性 (2-3周)
- [ ] UI自动化测试 (Playwright集成)
- [ ] 性能测试 (可选)
- [ ] 测试报告可视化
- [ ] CI/CD集成
六、技术难点与解决方案
6.1 AI生成的用例质量保证
问题: AI生成的用例可能不够准确
解决方案:
- 精心设计Prompt模板,提供足够上下文
- 使用多AI模型并行生成,选择最优结果
- 人工审核机制,支持用例编辑
- 基于执行历史反馈优化
6.2 测试用例的动态参数处理
问题: 用例间可能存在数据依赖(如登录获取token)
解决方案:
java
// 执行上下文支持变量存储
public class ExecutionContext {
private Map<String, Object> variables = new HashMap<>();
public void setVariable(String key, Object value) {
variables.put(key, value);
}
public Object getVariable(String key) {
return variables.get(key);
}
}
// 用例中使用变量
{
"headers": {
"Authorization": "Bearer ${token}" // 引用变量
}
}
// 变量解析器
public class VariableResolver {
public String resolve(String template, ExecutionContext context) {
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
Matcher matcher = pattern.matcher(template);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String varName = matcher.group(1);
Object value = context.getVariable(varName);
matcher.appendReplacement(result, String.valueOf(value));
}
matcher.appendTail(result);
return result.toString();
}
}6.3 UI测试的稳定性
问题: UI测试容易受页面加载、元素定位等影响
解决方案:
- 使用Playwright的自动等待机制
- 智能重试策略
- 多种元素定位策略(ID > CSS > XPath)
- 截图+日志详细记录
七、后续扩展方向
- 测试数据管理: 集成测试数据生成工具
- Mock服务: 集成WireMock支持接口Mock
- 持续测试: 与Jenkins/GitLab CI深度集成
- 测试覆盖率: 集成JaCoCo分析代码覆盖率
- 智能调度: 基于AI预测最优测试执行顺序
- 多环境支持: 测试环境管理与切换
八、总结
基于你现有的Spring Boot + AI架构,完全可以实现一个强大的AI自动化测试平台。核心优势:
- ✅ 复用现有能力: AI集成、数据库、Web框架都已就绪
- ✅ 技术栈统一: 全Java生态,无需学习新语言
- ✅ 灵活扩展: 模块化设计,支持多种测试类型
- ✅ AI增强: 从用例生成到结果分析全流程AI辅助
建议从API测试的MVP开始,快速验证可行性,再逐步扩展UI测试、性能测试等高级功能。