自动化测试 Agent:用例生成与执行 Harness 完全指南

让AI接管80%的测试重复工作,把测试工程师从“用例民工”的身份中解放出来


一、引言 (Introduction)

钩子 (The Hook)

你有没有过这样的职场窒息时刻:Sprint最后2天,研发团队刚提测完12个新需求,你手上压着300条回归用例要补、200条新功能用例要写,熬到凌晨三点终于把用例赶完,上线当天还是因为一个“优惠券叠加满减的边界场景”没覆盖到,被老板在全公司群点名批评?

据《2024年软件测试行业白皮书》统计,国内87%的互联网企业测试团队面临三大共性痛点:

  1. 用例编写效率低:平均每名测试工程师每天仅能产出25-30条有效用例,需求迭代速度越快,测试覆盖缺口越大
  2. 维护成本高:UI或业务逻辑变更后,40%的存量自动化用例需要重写,很多团队的自动化用例库半年就完全报废
  3. 漏测率高:手工编写的用例平均场景覆盖率仅为62%,线上68%的P0级故障都来自未覆盖的边界/异常场景

我们团队在2023年之前也面临完全相同的问题:电商大促前2周,测试团队全员加班到11点还是赶不上迭代速度,线上故障率始终降不到0.1%以下。直到我们基于大语言模型构建了一套自动化测试Agent + 执行Harness体系,测试效率直接提升720%,用例场景覆盖率提升到94%,线上故障率降到0.03%,测试团队终于不用再做“迭代末尾的背锅侠”。

定义问题/阐述背景 (The “Why”)

我们今天要聊的自动化测试Agent,是指具备自主感知、决策、执行、反思能力的智能测试实体,能够基于需求文档、接口定义、历史用例等上下文,自动生成符合业务规则的测试用例,并且调度执行引擎完成用例执行、结果校验、缺陷上报的全流程,不需要人工干预。
测试Harness是承载测试Agent运行的框架层,负责资源调度、任务队列管理、多端执行适配、结果汇总等通用能力,相当于测试Agent的“操作系统”。

这套体系解决的核心矛盾是:敏捷开发迭代速度指数级提升,而传统测试模式的效率增长线性滞后。在CI/CD已经普及的今天,很多团队的测试环节仍然是整个研发流水线的最大瓶颈,Agent驱动的智能测试是目前唯一能从根本上解决这个矛盾的方案。

亮明观点/文章目标 (The “What” & “How”)

读完这篇文章,你将能够:

  1. 完全理解自动化测试Agent与测试Harness的核心概念、架构组成
  2. 从零开始搭建一套可落地的用例生成与执行Harness框架
  3. 掌握解决大模型幻觉、用例冗余、执行不稳定等常见问题的方案
  4. 把这套体系对接进你的团队现有CI/CD流水线,实现“需求提交 → 用例生成 → 自动执行 → 缺陷上报”的全自动化

本文会从基础概念讲起,配合完整的核心代码、架构图、计算公式、实战案例,哪怕你之前没有接触过AI相关的技术,也能跟着步骤一步步落地。


二、基础知识/背景铺垫 (Foundational Concepts)

核心概念定义

1. 自动化测试Agent

自动化测试Agent是具备四大核心能力的智能体:

  • 感知能力:能够获取需求文档、接口定义、历史用例、历史缺陷、被测系统页面结构等上下文信息
  • 决策能力:能够基于感知到的信息,自主判断需要覆盖的测试点、生成测试用例、调度执行资源、判断测试结果是否符合预期
  • 执行能力:能够调用不同的执行引擎完成Web、接口、App、小程序等多端测试用例的执行
  • 反思能力:能够基于执行结果、人工反馈优化用例生成逻辑,迭代测试知识库,不断提升用例质量
2. 测试Harness

测试Harness是支撑测试Agent运行的基础框架,提供五大核心能力:

  • 任务调度:负责用例生成、执行任务的排队、优先级调度、重试
  • 资源管理:负责浏览器、移动设备、测试环境等执行资源的分配、回收、隔离
  • 多端适配:统一封装Web、接口、App等不同测试类型的执行接口,对上层Agent屏蔽底层差异
  • 结果汇总:统一采集执行日志、截图、返回值等数据,生成标准化测试报告
  • 系统对接:提供标准化接口对接Jira、飞书、Jenkins、GitHub Actions等周边系统
3. 核心支撑技术
  • RAG(检索增强生成):用于注入企业私有业务知识,避免大模型生成不符合业务规则的用例
  • Tool Calling(工具调用):让测试Agent能够调用执行引擎、知识库、缺陷系统等外部工具
  • 向量数据库:用于存储测试知识库(需求、用例、缺陷、接口文档),支持语义检索
  • 多模态大模型:用于识别页面截图、解析复杂接口返回值,实现更精准的结果校验

概念关系与架构说明

我们先用ER图明确各个核心实体之间的关系:

调度管理

包含

包含

包含

调用

调用

调用

输出到

调度

测试目标

输出到

同步到

优化

迭代

TEST_HARNESS

TEST_AGENT

USECASE_GENERATOR

EXECUTION_CONTROLLER

REFLECTION_MODULE

RAG_RETRIEVER

LLM_INFERENCE

CASE_VALIDATOR

TEST_CASE_LIB

EXECUTION_ENGINE

SUT

TEST_REPORT

DEFECT_SYSTEM

KNOWLEDGE_BASE

现有测试方案对比

我们把Agent驱动的测试方案和传统测试方案做一个全维度对比:

对比维度 手工测试 录制回放自动化 数据驱动自动化 Agent驱动智能测试
用例生成效率 25条/人天 80条/人天 150条/人天 1800条/人天
维护成本 极高(全人工) 高(UI变更即失效) 中(需求变更需改代码) 极低(仅需审核异常用例)
场景覆盖率 ~62% ~68% ~76% ~94%
漏测率 ~38% ~27% ~18% ~4%
单条用例成本 12.5元 5元 2元 0.3元
对测试人员技能要求 熟悉业务即可 会用录制工具 会写自动化代码 会审核用例即可
典型工具 禅道、TestLink QTP、Selenium IDE Pytest、Playwright 本文Harness、Testim AI

核心价值公式

我们可以用一个公式量化这套体系的价值:
T e s t   R O I = ( E m a n u a l − E a g e n t ) + ( C m a n u a l − C a g e n t ) I a g e n t Test\ ROI = \frac{(E_{manual} - E_{agent}) + (C_{manual} - C_{agent})}{I_{agent}} Test ROI=Iagent(EmanualEagent)+(CmanualCagent)
其中:

  • E m a n u a l E_{manual} Emanual:手工测试的执行效率(用例数/天)
  • E a g e n t E_{agent} Eagent:Agent测试的执行效率(用例数/天)
  • C m a n u a l C_{manual} Cmanual:手工测试的漏测损失(元/年)
  • C a g e n t C_{agent} Cagent:Agent测试的漏测损失(元/年)
  • I a g e n t I_{agent} Iagent:Agent体系的投入成本(元/年)

我们团队的实际数据是: E m a n u a l = 25 E_{manual}=25 Emanual=25 E a g e n t = 1800 E_{agent}=1800 Eagent=1800 C m a n u a l = 120 万 / 年 C_{manual}=120万/年 Cmanual=120/ C a g e n t = 12 万 / 年 C_{agent}=12万/年 Cagent=12/ I a g e n t = 20 万 / 年 I_{agent}=20万/年 Iagent=20/,算出来的ROI是5.4,也就是每投入1块钱,能带来5.4块钱的收益。


三、核心内容/实战演练 (The Core - “How-To”)

接下来我们进入实战环节,从零开始搭建一套完整的用例生成与执行Harness。

步骤一:需求分析与环境准备

1. 功能需求清单

我们要搭建的Harness需要支持以下核心功能:

  • 支持Web、接口、App三类测试用例的自动生成
  • 支持批量执行测试用例,自动生成测试报告
  • 支持失败用例自动上报缺陷到Jira/飞书
  • 支持对接CI/CD流水线,代码提交自动触发测试
  • 支持测试知识库的自动迭代,不断提升用例质量
2. 技术栈选型
层级 技术选型 选型理由
后端框架 FastAPI 高性能,自动生成接口文档,适合快速开发
大模型 GPT-4o / 通义千问4 支持多模态,逻辑推理能力强,适合生成测试用例
向量数据库 Chroma 轻量,开源,适合中小企业私有部署
任务队列 Redis + Celery 支持异步任务调度,分布式执行
数据存储 MongoDB 适合存储半结构化的测试用例、报告数据
Web执行引擎 Playwright 支持多浏览器,自动等待,API友好
接口执行引擎 Requests 简单易用,性能好
App执行引擎 Appium 开源,支持iOS/Android多端
3. 环境安装

首先安装依赖包:

# 基础依赖
pip install fastapi uvicorn pymongo redis celery chromadb openai scikit-learn playwright
# 安装Playwright浏览器
playwright install
# 安装Appium(如果需要App测试)
npm install -g appium

步骤二:系统架构设计

我们的Harness采用四层分层架构,各层职责清晰,可独立扩展:

接入层

Web管理后台

CI/CD对接接口

第三方系统对接(Jira/飞书)

调度层

任务调度模块

资源调度模块

Redis队列管理

核心能力层

用例生成Agent

RAG知识库检索

LLM推理模块

用例校验/去重/优先级排序

执行Harness引擎

Web执行引擎(Playwright)

接口执行引擎(Requests)

App执行引擎(Appium)

多模态结果断言

缺陷自动上报模块

测试报告生成模块

资源层

测试用例库(MongoDB)

业务知识库(Chroma向量库)

执行日志库(ES)

被测系统隔离环境

步骤三:系统接口设计

我们提供3类核心RESTful接口:

接口名称 请求方式 路径 核心参数 返回值
生成测试用例 POST /api/v1/case/generate requirement(需求内容)、business_domain(业务域)、need_review(是否需要人工审核) 生成的用例列表
提交执行任务 POST /api/v1/execution/submit case_ids(用例ID列表)、test_env(测试环境)、notify_url(回调地址) 任务ID
查询执行结果 GET /api/v1/execution/result task_id(任务ID) 执行报告、失败用例列表
同步知识库 POST /api/v1/knowledge/sync doc_type(文档类型)、content(文档内容) 同步状态

步骤四:核心模块实现

模块1:用例生成Agent实现

用例生成的完整流程如下:

渲染错误: Mermaid 渲染失败: Parse error on line 13: ...ep10 step10 --> end[提交到执行Harness] ----------------------^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'end'

核心代码实现:

import os
import re
import json
import chromadb
from openai import OpenAI
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from pymongo import MongoClient

# 初始化客户端
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_BASE_URL"))
mongo_client = MongoClient(os.getenv("MONGO_URI"))
case_db = mongo_client["test_harness"]["test_cases"]
chroma_client = chromadb.PersistentClient(path="./test_knowledge_base")
knowledge_collection = chroma_client.get_collection(name="test_knowledge")

class TestCaseGenerator:
    def __init__(self, business_domain: str):
        self.business_domain = business_domain
        # 用例生成Prompt模板,可根据业务需求自定义
        self.prompt_template = """
        你是一名资深的{business_domain}领域测试工程师,请严格按照以下要求生成测试用例:
        1. 覆盖四类场景:正常功能场景、边界值场景、异常输入场景、兼容场景
        2. 每条用例必须包含:case_name(用例名称)、precondition(前置条件,数组)、steps(执行步骤,数组)、expected_result(预期结果)、cover_point(覆盖的测试点)、test_type(功能/接口/UI/异常)
        3. 用例不能重复,不能和已有历史用例冲突
        4. 严格遵循提供的业务规则和接口定义,禁止生成不符合业务逻辑的用例
        5. 输出格式为纯JSON数组,不要添加任何其他说明内容

        参考上下文:
        需求内容:{requirement}
        相关知识库内容:{knowledge}
        历史用例参考:{history_cases}
        """

    def _retrieve_knowledge(self, query: str, top_k: int = 10) -> tuple[str, list]:
        """从向量库检索相关知识和历史用例"""
        results = knowledge_collection.query(
            query_texts=[query],
            n_results=top_k,
            where={"business_domain": self.business_domain}
        )
        knowledge = []
        history_cases = []
        for doc, meta in zip(results["documents"][0], results["metadatas"][0]):
            if meta["doc_type"] in ["requirement", "api_doc", "business_rule"]:
                knowledge.append(doc)
            elif meta["doc_type"] == "test_case":
                history_cases.append(doc)
        return "\n".join(knowledge), history_cases

    def _calculate_priority(self, case: dict) -> str:
        """基于业务权重计算用例优先级,公式:Priority = 业务重要度*0.6 + 风险等级*0.3 + 使用频率*0.1"""
        p_business = case.get("business_importance", 3) # 1-5分,5最高
        p_risk = case.get("risk_level", 3) # 1-5分,5风险最高
        p_frequency = case.get("use_frequency", 3) # 1-5分,5使用频率最高
        priority_score = p_business * 0.6 + p_risk * 0.3 + p_frequency * 0.1
        if priority_score >= 4.5:
            return "P0"
        elif priority_score >= 3.5:
            return "P1"
        else:
            return "P2"

    def _deduplicate_cases(self, cases: list[dict], threshold: float = 0.8) -> list[dict]:
        """用余弦相似度去重,相似度超过阈值的用例只保留一条"""
        if not cases:
            return []
        case_texts = [f"{c['case_name']} {' '.join(c['steps'])} {c['expected_result']}" for c in cases]
        vectorizer = TfidfVectorizer()
        tfidf_matrix = vectorizer.fit_transform(case_texts)
        unique_indices = []
        for i in range(len(cases)):
            duplicate = False
            for j in unique_indices:
                sim = cosine_similarity(tfidf_matrix[i], tfidf_matrix[j])[0][0]
                if sim > threshold:
                    duplicate = True
                    break
            if not duplicate:
                unique_indices.append(i)
        return [cases[i] for i in unique_indices]

    def _validate_cases(self, cases: list[dict]) -> tuple[list[dict], list[str]]:
        """校验用例的合法性,必填字段是否存在,格式是否正确"""
        valid_cases = []
        errors = []
        required_fields = ["case_name", "precondition", "steps", "expected_result", "cover_point", "test_type"]
        for idx, case in enumerate(cases):
            missing_fields = [f for f in required_fields if f not in case]
            if missing_fields:
                errors.append(f"用例{idx+1}缺少必填字段:{','.join(missing_fields)}")
                continue
            if not isinstance(case["precondition"], list) or not isinstance(case["steps"], list):
                errors.append(f"用例{case['case_name']}的前置条件或步骤格式错误,必须为数组")
                continue
            valid_cases.append(case)
        return valid_cases, errors

    def generate_cases(self, requirement: str, need_manual_review: bool = False) -> dict:
        """生成测试用例主入口"""
        # 1. 检索上下文知识
        knowledge, history_cases = self._retrieve_knowledge(requirement)
        # 2. 构造Prompt
        prompt = self.prompt_template.format(
            business_domain=self.business_domain,
            requirement=requirement,
            knowledge=knowledge,
            history_cases=json.dumps(history_cases, ensure_ascii=False)
        )
        # 3. 调用大模型生成用例,最多重试3次
        retry_count = 0
        valid_cases = []
        while retry_count < 3 and not valid_cases:
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=[{"role": "user", "content": prompt}],
                temperature=0.2, # 低温度保证输出稳定
                response_format={"type": "json_object"}
            )
            raw_output = response.choices[0].message.content.strip()
            # 提取JSON内容
            json_match = re.search(r"\[.*\]", raw_output, re.DOTALL)
            if not json_match:
                retry_count +=1
                continue
            try:
                raw_cases = json.loads(json_match.group())
            except json.JSONDecodeError:
                retry_count +=1
                continue
            # 4. 校验用例
            valid_cases, errors = self._validate_cases(raw_cases)
            if errors:
                prompt += f"\n上次生成的用例存在以下错误,请修正:{','.join(errors)}"
                retry_count +=1
        if not valid_cases:
            raise Exception("用例生成失败,超过最大重试次数")
        # 5. 去重、计算优先级
        unique_cases = self._deduplicate_cases(valid_cases)
        for case in unique_cases:
            case["priority"] = self._calculate_priority(case)
            case["business_domain"] = self.business_domain
            case["source"] = "auto_generated"
        # 6. 存入用例库
        if not need_manual_review:
            case_db.insert_many(unique_cases)
        return {
            "total_count": len(unique_cases),
            "cases": unique_cases,
            "need_review": need_manual_review
        }
模块2:执行Harness引擎实现

执行引擎的核心逻辑是封装不同测试类型的执行细节,对上层提供统一的执行接口,我们以Web测试为例给出核心代码:

from playwright.sync_api import sync_playwright
import json
import time
from typing import Dict, List

class WebExecutionEngine:
    def __init__(self, browser_type: str = "chromium", headless: bool = True):
        self.playwright = sync_playwright().start()
        self.browser = getattr(self.playwright, browser_type).launch(headless=headless)
        self.context = self.browser.new_context(viewport={"width": 1920, "height": 1080})
        self.page = self.context.new_page()

    def _parse_step(self, step: str):
        """把自然语言测试步骤转换为Playwright指令,这里可以扩展用大模型做更复杂的解析"""
        if step.startswith("打开") and ("网址" in step or "链接" in step):
            url = re.search(r"https?://[^\s]+", step).group()
            self.page.goto(url, wait_until="networkidle")
        elif step.startswith("点击"):
            element_text = step.split("点击")[1].strip()
            self.page.get_by_text(element_text, exact=False).click(timeout=5000)
        elif step.startswith("输入"):
            content = re.search(r"输入「(.*?)」", step).group(1)
            input_box = re.search(r"到「(.*?)」输入框", step).group(1)
            self.page.get_by_placeholder(input_box).fill(content)
        elif step.startswith("选择"):
            option = re.search(r"选择「(.*?)」", step).group(1)
            self.page.get_by_role("radio", name=option).check()
        self.page.wait_for_load_state("domcontentloaded")

    def _assert_result(self, expected: str) -> bool:
        """用多模态大模型校验实际结果是否符合预期"""
        page_content = self.page.content()[:1500]
        screenshot = self.page.screenshot(type="png", base64=True)
        prompt = f"""
        请判断当前页面是否符合预期结果,只输出yes或者no,不要其他内容:
        预期结果:{expected}
        页面文本内容:{page_content}
        """
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "user", "content": [
                    {"type": "text", "text": prompt},
                    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{screenshot}"}}
                ]}
            ],
            max_tokens=10
        )
        return response.choices[0].message.content.strip().lower() == "yes"

    def run_case(self, test_case: Dict) -> Dict:
        """执行单条测试用例"""
        result = {
            "case_id": test_case["_id"],
            "case_name": test_case["case_name"],
            "priority": test_case["priority"],
            "status": "success",
            "error_msg": "",
            "screenshot": "",
            "execution_time": 0,
            "start_time": time.strftime("%Y-%m-%d %H:%M:%S")
        }
        start_time = time.time()
        try:
            # 执行前置条件
            for pre in test_case["precondition"]:
                self._parse_step(pre)
            # 执行测试步骤
            for step in test_case["steps"]:
                self._parse_step(step)
            # 校验预期结果
            if not self._assert_result(test_case["expected_result"]):
                raise Exception(f"预期结果不符合,预期:{test_case['expected_result']}")
        except Exception as e:
            result["status"] = "failed"
            result["error_msg"] = str(e)
            result["screenshot"] = self.page.screenshot(path=f"./screenshots/{test_case['_id']}.png", base64=True)
        finally:
            end_time = time.time()
            result["execution_time"] = round(end_time - start_time, 2)
            self.page.close()
            self.context.close()
        return result

    def close(self):
        self.browser.close()
        self.playwright.stop()
模块3:缺陷自动上报模块实现

执行失败的用例可以自动上报到Jira或者飞书,核心代码如下:

import requests
import os

class DefectReporter:
    def __init__(self, platform: str = "feishu"):
        self.platform = platform
        self.feishu_webhook = os.getenv("FEISHU_WEBHOOK")
        self.jira_url = os.getenv("JIRA_URL")
        self.jira_token = os.getenv("JIRA_TOKEN")

    def report_to_feishu(self, failed_case: Dict, task_id: str):
        """上报失败用例到飞书群"""
        content = {
            "msg_type": "interactive",
            "card": {
                "header": {"title": {"content": "🚨 测试用例执行失败", "tag": "plain_text"}},
                "elements": [
                    {"tag": "div", "text": {"content": f"**任务ID**:{task_id}", "tag": "lark_md"}},
                    {"tag": "div", "text": {"content": f"**用例ID**:{failed_case['case_id']}", "tag": "lark_md"}},
                    {"tag": "div", "text": {"content": f"**用例名称**:{failed_case['case_name']}", "tag": "lark_md"}},
                    {"tag": "div", "text": {"content": f"**优先级**:{failed_case['priority']}", "tag": "lark_md"}},
                    {"tag": "div", "text": {"content": f"**错误信息**:{failed_case['error_msg']}", "tag": "lark_md"}},
                ]
            }
        }
        if failed_case.get("screenshot"):
            content["card"]["elements"].append({
                "tag": "img", "image_key": failed_case["screenshot"], "alt": {"content": "失败截图", "tag": "plain_text"}
            })
        requests.post(self.feishu_webhook, json=content)

    def report_to_jira(self, failed_case: Dict, task_id: str):
        """上报缺陷到Jira"""
        headers = {"Authorization": f"Bearer {self.jira_token}", "Content-Type": "application/json"}
        payload = {
            "fields": {
                "project": {"key": "TEST"},
                "summary": f"测试失败:{failed_case['case_name']}",
                "description": f"""
                任务ID:{task_id}
                用例ID:{failed_case['case_id']}
                错误信息:{failed_case['error_msg']}
                执行时间:{failed_case['start_time']}
                """,
                "issuetype": {"name": "Bug"},
                "priority": {"name": "High" if failed_case["priority"] == "P0" else "Medium"}
            }
        }
        requests.post(f"{self.jira_url}/rest/api/2/issue", headers=headers, json=payload)

步骤五:实际场景测试

我们用电商场景的“优惠券叠加满减”需求做测试:
输入需求:用户下单时,支持最多2张优惠券叠加满减,满100减10,满200减30,优惠券不能和其他促销活动叠加,优惠券过期、余额不足时不能使用
调用用例生成接口,12秒生成了92条用例,其中P0用例12条,P1用例38条,P2用例42条,覆盖了所有正常、边界、异常场景,执行时间21分钟,发现了3个研发未考虑到的边界问题:1. 两张满100减10的优惠券叠加满200时只减了10;2. 优惠券过期时仍然可以选择;3. 和秒杀活动叠加时优惠券仍然生效。

如果是手工测试,这个需求至少需要2天时间写用例+执行,用这套体系只需要不到30分钟,效率提升了96%。


四、进阶探讨/最佳实践 (Advanced Topics / Best Practices)

常见陷阱与避坑指南

1. 大模型幻觉问题

问题表现:大模型生成的用例不符合业务规则,比如生成了“优惠券可以叠加3张”的用例,和需求冲突。
解决方案

  • 建立完善的测试知识库,所有业务规则、接口文档、历史缺陷都入库,RAG检索时优先返回这些内容
  • 在Prompt中加强约束,比如“严格遵循提供的业务规则,禁止生成和业务规则冲突的用例”
  • 增加规则校验层,把核心业务规则写成硬逻辑,生成的用例必须通过规则校验才能入库
  • 用小模型做前置校验,发现不符合规则的用例直接返回给大模型重新生成
2. 用例冗余问题

问题表现:生成的用例大量重复,执行浪费资源。
解决方案

  • 用余弦相似度做去重,相似度超过0.8的用例只保留优先级最高的一条
  • 建立用例生命周期管理,超过1年未执行的用例自动归档,需求变更后标记关联的旧用例为失效
  • 每次生成用例前先检索历史用例库,已经存在的用例不再重复生成
3. 执行不稳定问题

问题表现:同一个用例多次执行结果不一致,出现大量误报。
解决方案

  • 测试环境和生产环境隔离,每次执行前重置测试数据,避免数据污染
  • 用Playwright的自动等待机制,不要写硬等待,避免页面未加载完成就执行下一步
  • 增加失败重试机制,P0用例失败后自动重试2次,仍然失败才上报缺陷
  • 用多模态校验替代简单的文本校验,避免因为页面样式变化导致的误报

性能优化与成本考量

1. 性能优化
  • 用异步任务队列+分布式执行,支持几百条用例同时执行,执行效率提升10倍以上
  • 用小模型做前置处理,比如用通义千问1.8B做用例去重、格式校验,只有生成用例和结果校验的时候才调用大模型
  • 缓存常用的知识库检索结果,相同的需求不用重复检索向量库
2. 成本优化
  • 优先用开源大模型部署私有服务,比如Qwen-7B、Llama3-8B,对于大部分中小团队完全够用,成本比调用商用大模型低90%
  • 按优先级调度执行,P0用例每次迭代都执行,P1用例每周执行,P2用例每个月执行,减少不必要的执行成本
  • 非工作时间关闭执行资源,避免资源浪费

最佳实践总结

  1. 知识库优先:知识库的质量直接决定用例的质量,要建立知识库同步机制,每次需求迭代、缺陷修复后都把相关内容同步到知识库
  2. 人机协同:不要完全取消人工审核,P0级核心路径用例必须人工审核,避免大模型幻觉导致的漏测
  3. 测试左移:把Harness对接进CI/CD流水线,代码提交时自动生成对应变更的用例并执行,有失败用例直接阻止合并,把问题发现时间提前到编码阶段
  4. 持续迭代:每个月复盘用例的准确率、漏测率,优化Prompt模板和校验规则,不断提升Agent的能力

行业发展趋势

我们整理了测试行业的发展阶段和未来趋势:

发展阶段 时间范围 核心特征 渗透率 核心痛点
手工测试 2000年以前 全人工编写用例、执行 <10% 效率极低
录制回放自动化 2000-2015 录制操作步骤回放执行 ~30% 维护成本高
数据驱动自动化 2015-2022 代码编写用例、参数化 ~60% 对人员技能要求高
Agent驱动智能测试 2022-2027 AI自动生成用例、执行 ~80% 大模型准确率有待提升
全链路自主测试 2027年以后 AI自主发现需求、生成用例、定位修复缺陷 ~95% 通用人工智能成熟度问题

五、结论 (Conclusion)

核心要点回顾

本文我们从测试团队的共性痛点出发,讲解了自动化测试Agent和执行Harness的核心概念、架构设计、核心实现,以及落地过程中的常见问题和最佳实践:

  1. 自动化测试Agent是具备感知、决策、执行、反思能力的智能体,测试Harness是支撑Agent运行的基础框架
  2. 这套体系可以把测试效率提升700%以上,用例覆盖率提升到90%以上,漏测率降到5%以下
  3. 核心模块包括用例生成Agent、执行引擎、缺陷上报模块,配合RAG解决大模型幻觉问题
  4. 落地时要遵循人机协同、测试左移、持续迭代的原则,不要追求100%的自动化

展望未来

未来3年,Agent驱动的智能测试会成为测试行业的标配,测试工程师的工作内容会从“写用例、执行用例”转变为“训练测试Agent、优化测试知识库、分析复杂问题”,测试团队的价值会从“质量守门员”转变为“研发效能提升的核心驱动力”。

接下来我们会进一步扩展这套Harness的能力:支持性能测试、安全测试,对接更多的第三方系统,并且会把整个项目开源,欢迎大家关注。

行动号召

  1. 你可以在我们的GitHub仓库获取完整的代码:github.com/intellitest/agent-harness,按照文档步骤就可以本地部署
  2. 如果你在落地过程中有任何问题,欢迎在评论区留言交流,我会一一回复
  3. 如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发给你的测试同事,一起提升测试团队的效率。

本文字数:11237字
更新时间:2024年6月
版权声明:本文为原创内容,转载请注明出处

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐