Skip to content

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复用现有架构
ORMMyBatis-Flex现有数据访问层
AI集成beyondsoft-ai-spring3-starter复用现有多AI平台集成
API测试REST Assured 5.xJava生态最佳实践
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生成的用例可能不够准确

解决方案:

  1. 精心设计Prompt模板,提供足够上下文
  2. 使用多AI模型并行生成,选择最优结果
  3. 人工审核机制,支持用例编辑
  4. 基于执行历史反馈优化

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测试容易受页面加载、元素定位等影响

解决方案:

  1. 使用Playwright的自动等待机制
  2. 智能重试策略
  3. 多种元素定位策略(ID > CSS > XPath)
  4. 截图+日志详细记录

七、后续扩展方向

  1. 测试数据管理: 集成测试数据生成工具
  2. Mock服务: 集成WireMock支持接口Mock
  3. 持续测试: 与Jenkins/GitLab CI深度集成
  4. 测试覆盖率: 集成JaCoCo分析代码覆盖率
  5. 智能调度: 基于AI预测最优测试执行顺序
  6. 多环境支持: 测试环境管理与切换

八、总结

基于你现有的Spring Boot + AI架构,完全可以实现一个强大的AI自动化测试平台。核心优势:

  1. 复用现有能力: AI集成、数据库、Web框架都已就绪
  2. 技术栈统一: 全Java生态,无需学习新语言
  3. 灵活扩展: 模块化设计,支持多种测试类型
  4. AI增强: 从用例生成到结果分析全流程AI辅助

建议从API测试的MVP开始,快速验证可行性,再逐步扩展UI测试、性能测试等高级功能。

Copyright © 2025-present | 网站备案号:豫ICP备19038229号-1