ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI驱动操作流程测试:从用户手册到自动化用例的完整实践

AI驱动操作流程测试:从用户手册到自动化用例的完整实践 1. 项目背景与整体思路拆解1.1 为什么我要从用户手册切入操作流程测试做软件测试的人应该都有过这样的经历产品经理丢过来一份更新后的用户手册让你核对一下“操作流程测试用例”是否需要同步修改。打开一看章节结构大变按钮文案改了一半新增了好几个步骤于是你只能一头扎进文档和旧用例之间逐字比对改完用例再手动跑一遍冒烟一个下午就这么没了。我一直在想用户手册本质上就是产品操作流程最有权威性的“规格说明”而我们写操作流程测试用例本质上是在把文档里描述的动作翻译成可执行、可验证的脚本。既然翻译工作这么机械、这么重复那能不能用大模型做这个翻译能不能从“用户手册更新”直接驱动“自动化验证脚本”的更新这个项目就是围绕这个想法搭起来的AI驱动的操作流程测试输入是产品的用户手册输出是可直接在浏览器上跑的自动化验证用例。整个链路是“文档解析 → 结构化抽取 → 测试用例生成 → 自动执行验证”中间所有需要“人肉读文档、人肉写用例”的环节都尽量让AI代劳我只需要做审核和兜底。这个项目适合谁参考如果你是测试工程师想在团队里引入AI辅助测试却不知道从哪里下手或者你在做文档类产品被频繁的UI改动和用例维护折磨过又或者你是技术负责人想评估“AI Agent在测试领域到底能落地多少”——那这篇内容应该能给你一个从零到一、可以照着实现的案例。1.2 整体方案设计一条流水线而不是一个单点工具先说结论如果你只让AI“生成几条测试用例”那这个项目没有多大价值因为生成出来的东西大概率跑不通。真正有价值的是把整个链路串成一条自动化流水线让“文档更新”这件事能自动传导到“测试执行”环节。我把整个流程拆成了五个阶段阶段输入输出关键动作文档预处理PDF/Word/HTML用户手册清洗后的纯文本提取正文、合并章节、过滤噪音结构化抽取用户手册章节文本操作步骤JSON大模型抽取操作序列、预期结果用例生成操作步骤JSON测试用例集合补充前置条件、测试数据、断言点脚本映射测试用例集合可执行自动化脚本自然语言步骤映射到Selenium操作执行反馈自动化脚本测试报告、问题清单跑批、截图、定位失败原因这个设计最核心的一个决策是不要让大模型直接生成整段可运行的测试脚本而是先让它输出结构化的中间产物再用一个确定性较高的转译器把中间产物翻译成自动化操作。为什么要这么做我一开始也直接试过“把路径写进prompt让模型输出Selenium代码”结果非常不稳定——模型偶尔会把元素定位器写错偶尔会自己发明不存在的API甚至会在代码里加一些无效等待错误五花八门。后来我换了个思路大模型做它最擅长的事——理解语义、抽取步骤、归纳预期结果而机械的“JSON转Selenium”动作交给规则引擎去做。这样即使大模型换一个版本、换一个厂商只要它输出的JSON结构是稳定的下游的自动化执行就不会受影响。这个分层解耦的思路是整个项目真正能落地的关键。1.3 为什么这个方案能解决真实痛点我统计过一个中等复杂度模块的回归测试手工维护一套覆盖30条核心操作流程的用例每次版本迭代平均要花2.5个人日去同步用户手册和用例而一旦漏改了某条流程的断言线上出问题后排查成本更高。这个项目跑通之后同一份手册更新流水线在十几分钟内就能给出新的测试结果和差异报告我的角色从“逐字翻译官”变成了“结果审核者”。当然AI不是万能的它不能替你判断“这个流程是不是用户真正关心的”也不能替你设计复杂的测试数据组合。但它能把“文档—用例—脚本”之间那层大量重复的翻译工作吞掉这已经足够在生产环境里省下可观的时间了。2. 核心细节解析从手册文本到结构化用例2.1 用户手册解析这一步没做好后面全是垃圾整个流水线里我最想提醒大家重视的就是文档预处理。很多人以为把PDF扔给大模型就行实际上直接扔原文大模型会被各种格式噪音干扰抽取出来的步骤经常带上页眉页脚、目录信息、甚至“注意”“提示”这类非操作内容。我最终的预处理流程是这样的按章节拆分文档保留章节层级关系。用户手册通常有“1.1”“1.2”这种结构每个小节对应一个独立功能点按章节切分后大模型在单次请求里处理的内容更聚焦抽取质量明显提升。过滤非正文内容。目录、页眉页脚、版本记录、版权声明都要去掉。用Python的pdfplumber或beautifulsoup4提取文本后我会先跑一遍正则把页码、重复出现的页眉行清理掉。处理表格和图片。用户手册里大量操作步骤是“按钮名称”加“操作说明”的表格形式纯文本抽取后表格结构会丢失。我用的办法是如果提取到的文本里有明显的制表符或大量连续空格就按行拆分再用CSV格式喂给大模型同时在prompt里明确告诉模型“这是一个表格每一行是一条独立操作记录”。对步骤编号进行规整。很多手册的步骤是“1. 点击XX 2. 输入XX”这种格式但也有些手册是用星号、圆点甚至段落来描述的。我会先做一个正则归一化把所有步骤标记统一替换成“步骤N”这样大模型在抽取时不至于把段落文本当成操作步骤。这段代码是文档预处理的核心部分我一般这样处理import re import pdfplumber def extract_clean_text(pdf_path): raw_lines [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text page.extract_text() if text: raw_lines.extend(text.split(\n)) # 清理页眉页脚和页码 cleaned [] for line in raw_lines: line line.strip() if not line: continue if re.match(r^第\s*\d\s*页, line): continue if re.match(r^\d$, line): continue cleaned.append(line) return \n.join(cleaned)看起来简单但这一步直接影响后面大模型抽取的准确率我大概迭代了三四版才稳定下来。2.2 步骤抽取与预期结果生成Prompt工程的关键细节文档预处理完之后下一步就是把每个章节的文本喂给大模型让它输出结构化的操作步骤和预期结果。这一步的Prompt设计决定了抽取质量的上限。我用的系统提示词大致是这个思路你是一名资深的软件测试工程师请从给定的用户手册章节中提取操作流程。 要求 1. 只提取与用户操作直接相关的步骤忽略背景介绍、注意事项、常见问题等说明性内容。 2. 每一步必须包含“操作动作”和“操作对象”例如“点击”“输入”“选择”“拖拽”等动作以及对应的页面元素描述。 3. 每一步必须给出明确的“预期结果”预期结果要可观察、可检查避免使用“正常”“成功”这种模糊描述。 4. 如果某一步存在输入数据标注数据示例。 5. 输出严格遵循JSON格式不要输出任何额外文字。大模型的输出我要求它严格遵循一个固定的JSON Schema{ operation_flow: { flow_name: 订单创建流程, preconditions: [用户已登录, 购物车中有商品], steps: [ { step_id: 1, action: click, target: 立即结算按钮, data: , expected_result: 跳转到订单确认页面页面标题显示“确认订单” }, { step_id: 2, action: input, target: 收货地址输入框, data: 北京市朝阳区某街道1号, expected_result: 输入框显示对应地址内容 } ] } }注意几件事第一action我限定为click、input、select、hover、upload、assert_text、wait_for_element等有限集合这直接决定了后面规则引擎的映射复杂度第二target字段让模型写“用户能理解的元素描述”而不是让模型猜CSS选择器或XPath选择器的问题放到执行层去解决第三expected_result必须是可以被自动化验证的断言我甚至会在后处理里做一次校验如果某条预期结果包含“正常”“成功”“正确”这类词就自动打标记让模型重新生成。2.3 后处理校验大模型会犯错别把它的输出当真理大模型抽取结果里最常见的一类问题是“幻觉步骤”——手册里根本没提但模型顺着上下文自己编了一段操作。为了对付这个问题我做了一个两层的后处理第一层是规则校验。比如检查步骤数量是否与原文标记的步骤数一致检查action是否在允许集合内检查是否存在重复的step_id。如果校验不通过就把原文和模型的上一次输出一起发回给模型让它自我纠错。实测下来一轮纠错就能解决大部分格式问题。第二层是语义校验。我会把抽取出来的步骤序列和我自己人工设计的“关键步骤锚点”做一次模糊匹配比如一个订单流程里必须要有“提交订单”这个动作如果没有就报一个“关键步骤缺失”的警告。这一步不完全自动化但它能在执行之前提示我重点关注哪些用例。这些细节单独看都很简单但组合在一起整个流水线的稳定性才会有保障。3. 实操过程与核心环节实现3.1 环境准备与工程目录在动手写核心代码之前先说下我最终的运行环境。因为涉及大模型API调用和浏览器自动化环境的稳定性很重要。推荐的基础环境Python 3.10 以上版本大模型 API我用的OpenAI兼容接口国内厂商的兼容接口也可以Selenium 4.x配合webdriver-manager自动管理浏览器驱动pydantic做数据结构校验pytest做用例组织与断言我个人的工程目录是这样组织的ai_flow_test/ ├── data/ │ ├── manual.pdf # 用户手册源文件 │ └── manual_clean.txt # 预处理后的文本 ├── src/ │ ├── document_parser.py # 文档预处理 │ ├── llm_extractor.py # 大模型结构化抽取 │ ├── step_mapper.py # JSON步骤转Selenium操作 │ ├── runner.py # 自动化执行器 │ └── validator.py # 结果校验和报告生成 ├── tests/ │ └── test_order_flow.py # 生成的用例文件 └── config.yaml # 模型参数、浏览器配置等这个目录结构其实是在项目跑了三周之后才定下来的一开始所有逻辑都堆在一个脚本里后来加了报告、重试、缓存之后才拆开。提前规划好模块边界后续维护会轻松很多。3.2 大模型抽取模块的实现要点大模型调用这个模块我最想分享的是一个非常容易被忽略的点怎么保证模型输出是合法JSON。大模型偶尔会在JSON里加一些注释、尾逗号、或者用单引号代替双引号直接json.loads会报错。我最终的策略是在prompt最后强调“只输出JSON不要输出任何解释”。拿到响应后先尝试直接json.loads。如果失败用正则提取最外层花括号内的内容再做一次解析。还不行就把错误信息拼到prompt里发给模型让它“修正上一个JSON”。此外temperature参数一定要调低。我实测过temperature0.1和temperature0.7在结构化抽取任务上的表现差异非常大温度越高模型的自由发挥越离谱步骤描述会越来越花哨但可执行性越来越差。现在我把这个任务的temperature固定设在0.1左右max_tokens根据文档长度动态设置为600到1200。核心代码大致如下import json import openai def extract_flow_with_retry(client, chapter_text, schema, max_retries3): system_prompt 你是一名资深测试工程师请从用户手册中提取操作流程只输出JSON。 user_prompt f章节内容如下\n{chapter_text}\n\n请提取操作流程并严格遵循以下JSON结构\n{schema} for attempt in range(max_retries): try: resp client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: system_prompt}, {role: user, content: user_prompt} ], temperature0.1, max_tokens1000 ) content resp.choices[0].message.content # 提取JSON块 if json in content: content content.split(json)[1].split()[0] return json.loads(content) except (json.JSONDecodeError, KeyError, IndexError) as e: if attempt max_retries - 1: raise RuntimeError(f模型输出解析失败: {e}) user_prompt f\n上次输出无法解析为JSON错误信息{e}请重新输出严格合法的JSON格式。这套重试逻辑看着简单但它是整个流水线稳定性的兜底保障实测可以把单次抽取成功率从80%左右拉到接近100%。3.3 JSON步骤到Selenium操作的映射规则这是整个项目里我最花心思的部分。拿到大模型输出的JSON后如果只做“生成测试用例文档”那价值还不够我的目标是让它直接跑起来。映射规则我做了这么一张对照表JSON中的actionSelenium动作待定位目标clickelement.click()target描述的元素inputelement.send_keys(data)target描述的元素selectSelect(element).select_by_visible_text(data)target描述的下拉框hoverActionChains(driver).move_to_element(element).perform()target描述的元素uploadelement.send_keys(file_path)target描述的file inputassert_text查找元素并断言文本包含expected_resultexpected_result里的文本描述wait_for_element显式等待目标元素可点击target描述的元素关键难点在于“如何根据自然语言target描述找到页面上的元素”。比如模型输出的target是“立即结算按钮”但页面上这个按钮可能有多种实现方式可能是button也可能是a标签还可能是某个div绑定了点击事件。我最终实现了一个多策略定位器先尝试精确匹配text立即结算按钮、idsubmit_btn、namesubmit。再尝试模糊匹配用XPath匹配所有包含该文本的元素取第一个可见且可点击的。如果文本有变化比如“立即结算”变成了“去结算”我用语义相似度做兜底把所有可交互元素的文本提取出来和target描述做一次向量相似度匹配取相似度最高的那个。这个语义兜底的方案我一开始觉得不靠谱但实测下来非常好用尤其是面对前端频繁改文案的场景。from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def find_element_with_fallback(driver, target_desc, timeout10): strategies [ (By.LINK_TEXT, target_desc), (By.PARTIAL_LINK_TEXT, target_desc[:20]), (By.XPATH, f//*[text(){target_desc}]), (By.XPATH, f//*[contains(text(), {target_desc})]), ] for by, value in strategies: try: element WebDriverWait(driver, timeout).until( EC.element_to_be_clickable((by, value)) ) return element except Exception: continue raise ElementNotFoundError(f找不到元素: {target_desc})真正执行的时候我还会给每一步拍一张截图一方面方便失败定位另一方面可以作为“文档与真实界面差异”的证据——这个后面会细说。3.4 用一个小案例走通整条流水线为了验证方案可行性我当时用它跑了产品里一个“申请退款”的操作流程。用户手册里的描述是1. 进入“我的订单”页面。 2. 找到需要退款的订单点击“申请退款”。 3. 在退款原因下拉框中选择“商品与描述不符”。 4. 填写退款说明上传相关凭证。 5. 点击“提交申请”等待审核。经过预处理、大模型抽取之后输出的JSON步骤非常干净其中一个步骤是{ step_id: 3, action: select, target: 退款原因下拉框, data: 商品与描述不符, expected_result: 下拉框显示已选中“商品与描述不符” }然后我的step_mapper把这个JSON翻译成了Selenium操作实际执行时下拉框元素通过XPath定位成功断言校验也通过了。整个流程从输入文档到输出测试报告只花了不到5分钟而人工编写同一条用例通常需要半小时到一个小时。4. 常见问题与排查技巧实录4.1 大模型“幻觉”步骤的处理我遇到过最典型的一次是模型在“申请退款”流程里凭空加了一步“联系在线客服”手册里根本没有这个步骤。后来查明原因是因为这个章节里提到了“如有问题请联系客服”模型把这个注意性说明当成了操作步骤。解决办法是在prompt里明确限定“只提取带有明确操作动词、并由用户主动触发的步骤”同时在事后校验里增加“说明性文本过滤规则”。如果你也遇到类似问题不妨检查一下是不是文本清洗阶段把注意、提示这类词带进来了。4.2 页面元素定位不稳定的终极对策自动化测试最烦的就是元素定位失败。我这边遇到的情况是同一个按钮有时能点有时不能点后来发现是页面上有两个文本相似的元素一个可见一个隐藏。定位器返回了隐藏的那个点击时报错。我的对策分三层显式等待一定要给足等元素可见且可点击而不是等元素出现。定位策略一定要有优先级顺序精确匹配优先于模糊匹配避免模棱两可。如果同一页面有多个候选元素按“是否可见、是否可点击”过滤后再返回而不是返回第一个。这一套组合打下来元素定位的稳定性从70%提升到了95%以上剩余的5%基本是因为前端临时改版造成的需要人工介入。4.3 API成本和速度控制大模型调用是会有成本的尤其是处理几十个章节的完整用户手册。为了控制成本和速度我做了两件事加了一层缓存按章节标题文本的哈希值做key如果文档没有变化直接读缓存不重复调用API。模型分层先用便宜快速的小模型如gpt-4o-mini跑完所有章节再用更强的大模型只处理“关键流程”或者“校验不通过”的章节。这条优化路径让我每本手册的AI处理成本从原来的几十元降到了个位数而且速度提升了接近一倍。如果你在生产环境跑这个流水线成本控制是必须考虑的。4.4 常见问题速查表问题现象可能原因解决方法模型输出的JSON无法解析输出包含解释性文字或格式错误增加重试机制拼上错误信息重新请求抽取步骤凭空多出操作说明性文字被当成操作步骤加强文本清洗prompt中明确“只提取主动操作”点击元素时报ElementNotInteractable定位到隐藏元素或未等元素可交互改显式等待条件为可点击过滤隐藏元素下拉框选择失败选项文本有空格或动态加载延迟使用Select的select_by_visible_text前先等待选项出现预期结果断言不稳定页面异步加载导致断言过早执行断言前增加显式等待等待目标文本出现在页面中调用大模型接口超时单次请求内容过长按章节拆分处理控制单次输入长度4.5 几个值得长期坚持的工程习惯最后分享几个我在项目迭代中沉淀下来的习惯这些习惯保证了流水线在日常运行中不会“三天两头罢工”第一保留每一步的原始执行日志和截图。自动化测试失败时最怕的就是“当时环境什么样”完全无从还原。我现在每个用例跑完都会输出一份带时间戳的HTML报告里面包含每个步骤的截图、耗时、定位方式。排查问题时效率高到飞起。第二不要轻易升级依赖库版本。Selenium、浏览器驱动、大模型SDK这些组件升级一时爽升级完可能就会冒出一堆兼容性问题。我现在的做法是固定所有依赖版本只有在有明确需求时才升级并且升级后先跑一遍全部回归用例。第三把AI的生成结果当成“初稿”而不是“终稿”。这个项目的目标不是让AI完全替代测试工程师而是让工程师从重复劳动里解脱出来把精力放到更高级的测试设计上。我现在的日常工作模式是AI先跑一遍流程生成用例并执行我再针对失败项和风险项做人工分析。AI帮我完成了80%的基础工作而那20%需要判断力的场景才是我真正产生价值的地方。如果你也想在团队里落地类似的东西我的建议是先选一个文档结构清晰、UI相对稳定、流程不太复杂的功能模块做试点跑通之后再逐步扩大范围。千万不要一上来就想着全量自动化那样只会被各种边界问题淹没。AI驱动的操作流程测试核心价值是让测试用例的维护成本大幅下降它不能解决“测试设计本身”的问题但解决“怎么把文档变成可执行验证”这个问题已经非常值了。
返回列表