简介:面向通讯行业测试开发人员的一份AI提效方案设计PDF,源自中兴通讯一线测试域AI应用负责人的实践总结。文档针对FTTR组网转型带来的测试复杂度上升、用例冗余和自动化脚本交付效率低等问题,系统介绍了基于大模型的端到端提效方案,对比提示工程、RAG与精调选型后,确定RAG为最优路径。内容覆盖AI辅助测试设计、脚本开发、执行分析等环节,包含GWT生成测试点、复用用例检索、DSL设计及RF关键字脚本生成等具体技术实践,并详述知识获取、建模、评估与应用的知识工程闭环,支撑AI能力持续改进。资源包共1个PDF文件,大小6.37MB,已有105人学习。适合具备软件测试基础、关注通信行业测试效率提升的研发人员与技术管理者,可直接获取完整技术方案与落地经验,用于优化自身测试开发流程,并为后续探索自生成、自校验、自修复等全流程自动化打下基础。
1. 为什么通讯行业的端到端测试,卡在“从需求到脚本”这一段
通讯行业的端到端测试,通常要覆盖核心网、接入网、业务平台和终端侧的完整信令链路。做过的人都知道,测试用例设计还能靠经验堆,真正吃时间的是“拿到需求文档之后到第一条自动化脚本跑通”这段路:解析需求、梳理接口、设计场景、拼报文、写断言、调时序,每一步都在消耗测试开发工程师的工时。AI测试开发想真正提效,切入点不是把已有脚本跑得更快,而是把“需求到脚本”这段人力密集的转换过程自动化。这篇笔记要讲的,就是一套基于AI的端到端测试开发提效方案:从需求解析、场景生成,到自动化脚本生成与自愈的完整链路,以及通讯行业落地时躲不开的参数选择和踩坑点。
2. 把“需求到脚本”拆成四段流水线:需求解析、场景生成、脚本生成、脚本自愈
2.1 需求解析:用LLM把自然语言需求变成结构化测试意图
需求文档在通讯行业通常是Word、PDF或企业知识库页面,内容包含业务描述、信令流程、接口定义、字段约束。常见做法是先抽文本,再交给LLM做信息抽取。这里的关键是不要直接让LLM“写测试用例”,而是先让它输出一个结构化的测试意图(test intent):前置条件、操作步骤、预期结果、关联接口、重要程度。你可以用JSON Schema约束输出,例如:
{ "intent_id": "INT-0001", "source": "5G语音业务需求v2.3.docx", "preconditions": ["UE_A_REGISTERED", "UE_B_REGISTERED", "IMS_SESSION_ESTABLISHED"], "steps": [ { "action": "SEND_INVITE", "target": "SBC", "params": { "caller": "139XXXX0001", "callee": "139XXXX0002", "media_profile": "AMR-WB" } } ], "expected": [ "SBC返回183响应且携带SDP", "UE_B收到RING事件" ], "related_interfaces": ["UE-SBC", "SBC-CSCF"], "priority": "P1" }这个JSON的价值在于每一段后续流程都可以独立校验:前置条件是否可建立、步骤能否映射到已有工具函数、预期结果是否可断言。解析阶段要设置“抽取置信度”,低于0.7的字段必须标记为待人工确认。我一般把temperature设为0,让LLM只做抽取不做发挥,同时用prompt里的few-shot示例固定输出格式。注意,不要在这个阶段让模型补充“你认为应该有的步骤”,那会污染后续场景生成。
2.2 场景生成:从接口契约和历史流量里补全边界与异常
需求解析只解决了“用户说了什么”,还要解决“用户没说但系统会遇到什么”。通讯系统最怕的是异常场景:对端无响应、超时重发、消息乱序、编解码错误、网络闪断。让AI生成这些场景,需要喂给它接口契约(OpenAPI、proto或ASN.1)和历史抓包。常见做法是把正常流程的报文作为种子,让LLM按故障模型(超时、丢包、重复、篡改、乱序、超大字段)生成变体。这里的关键是每生成一个场景,都要能回溯到“它是在哪个正常消息上做的哪种变异”,否则测试结果无法分析。
跑过一百个需求后你会发现,LLM生成的边界场景里,有价值的新场景占20%不到,大部分是排列组合出来的重复项。解决方法是维护一个“场景指纹库”,用接口名+消息类型+变异操作做哈希,生成时先查重。另外一个实用技巧是让AI同时输出“为什么这个场景可能触发缺陷”,这个理由会帮助测试工程师决定是否保留。对于通讯行业,我建议把变异源限定在“会话建立、会话保持、会话释放”三个主流程上,因为绝大多数现网故障都发生在这三段。
2.3 脚本生成:从意图到可执行的自动化脚本
拿到结构化意图后,下一步是翻译成自动化测试脚本。通讯行业常用的自动化框架有Robot Framework、pytest、以及厂商自研的TAP。我的选择是pytest + requests + aioquic,如果是传统信令协议就加上scapy。脚本生成策略不是让LLM直接输出整个文件,而是先输出“调用序列”,再按序列填充每个操作的具体参数。
这一步的提示词里必须写清楚三件事:框架内已有的工具函数清单、断言风格规范、以及禁止使用的API。比如你期望生成的是:
def test_call_flow(env, user_a, user_b): # 前置:注册 env.ue.register(user_a) env.ue.register(user_b) # 主流程:INVITE invite = env.sbc.send_invite( caller=user_a, callee=user_b, media_profile="AMR-WB" ) assert invite.sip_status == 183, f"expect 183, got {invite.sip_status}" # 等待被叫响铃 ring = env.ue.wait_ringing(user_b, timeout=10) assert ring, "UE-B should ring but did not"注意断言风格:不要只做“接口返回200”的弱断言,要断到业务结果(UE是否响铃)。这个要靠提示词约束:要求每个用例至少有一个业务级断言。此外,要把超时参数暴露成环境变量或配置项,而不是写死在代码里。AI生成脚本后,我会先用ruff做静态检查,再用pytest --collect-only确认函数能被正确收集,两关都过才进入下一环节。
2.4 脚本自愈:让AI处理元素漂移和断言失效
端到端测试跑了一段时间后,最烦人的就是“昨天还好好的今天挂了”。一部分是真实缺陷,一部分是环境变化、页面元素变化或时序抖动。脚本自愈的思路是:当脚本执行失败时,把失败日志、截图、响应报文喂给一个专门的自愈Agent,让它分析失败类别。如果判断是元素定位失效,则让它尝试用新的XPath或CSS定位器替换,并重新执行;如果判断是时序波动,则调整等待策略;如果判断是断言过强,则不自动修改,而是标记为“需人工判断”。
自愈功能必须设防呆:同一脚本连续失败两次就停止自愈,转入人工处理。否则AI会陷入“改一次跑一次,越改越偏”的死循环,把环境偶发问题当成脚本问题处理,反而引入更多噪声。我建议自愈Agent每次修改后都生成一个diff摘要,存到测试资产库,这样你随时能追溯AI到底改了什么。这个功能用下来,真正能自动修复成功的比例大约在40%左右,但剩下60%的“成功闯入人工”会节省大量排查时间。
3. 最小可复现方案:用LLM API + Python模板引擎跑通一条端到端链路
3.1 设计一个“需求→脚本”的中间表示
不要直接让LLM从需求文本生成pytest文件,否则很难控制质量和可调试性。我建议中间加一层DSL——一个比JSON稍微宽松的“测试动作序列”中间表示。用YAML描述,因为YAML能写注释,便于人工审阅。示例:
testcase: name: "5G语音主叫流程" preconditions: - "UE_A_ATTACH" - "UE_B_ATTACH" actions: - step: "SEND_INVITE" from: "UE_A" to: "SBC" params: caller: "$ENV.CALLER" callee: "$ENV.CALLEE" media_profile: "AMR-WB" expect: - status_code: [183] timeout: 5 - step: "WAIT_RING" target: "UE_B" expect: - event: "RING" timeout: 10这个YAML是LLM和代码生成之间的“黑匣子”接口。好处有三点:第一,人审YAML比审代码快,十分钟能扫完二十条用例的动作序列;第二,同一份YAML可以同时生成pytest和Robot脚本,只要写两套模板;第三,YAML本身是需求基线,需求变更时用git diff就能看出哪些步骤变了,进而定位需要重跑的用例。这个中间表示是整套方案里最值得先写死的部分,它的字段规范一旦定下来,后续所有AI交互都围绕它展开。
3.2 脚本生成代码示例与参数说明
下面是我常用的一段生成代码,基于OpenAI兼容接口,通过环境变量配置base_url和api_key,方便对接企业内网部署的LLM网关。核心逻辑是读取YAML中间表示,组装生成提示词,调用LLM生成pytest代码。
import os import json import yaml from openai import OpenAI client = OpenAI( api_key=os.environ.get("LLM_API_KEY"), base_url=os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1") ) def generate_test_script(yaml_path: str) -> str: with open(yaml_path, "r", encoding="utf-8") as f: test_spec = yaml.safe_load(f) prompt = build_prompt(test_spec) resp = client.chat.completions.create( model=os.environ.get("LLM_MODEL", "gpt-4o"), messages=[ {"role": "system", "content": "你是通讯行业测试开发专家。"}, {"role": "user", "content": prompt} ], temperature=0.2, max_tokens=4096, response_format={"type": "json_object"} ) result = json.loads(resp.choices[0].message.content) return result["python_code"] def build_prompt(spec: dict) -> str: return f""" 根据以下测试规格,生成一个pytest测试函数。 要求: 1. 使用框架封装好的 SIPClient / UE 类,不要自己构造底层socket。 2. 断言必须包含业务级验证,不能只验证状态码。 3. 禁止使用 time.sleep,改用 wait_until。 4. 输出JSON格式:{{"python_code": "..."}} 测试规格: {json.dumps(spec, ensure_ascii=False, indent=2)} """参数说明:temperature=0.2是平衡稳定性和少量灵活性——脚本生成要求确定性高,太高容易产生随机错误;max_tokens=4096是为了防止长脚本被截断,如果测试步骤超过十五步,我会把 max_tokens 提到 8192;response_format强制 JSON 输出,但如果你的模型网关不支持这个参数,就拆掉它,改用正则从返回内容里提取 ```python 代码块。另外,base_url一定要支持切换,通讯企业往往在自己的 AI 中台上部署私有模型,这里用环境变量可以避免写死地址。
3.3 生成脚本的质量校验与人工确认
生成出来的脚本不能直接进CI。第一步是静态检查:用ruff check做语法和风格检查,用pytest --collect-only确认能被收集;第二步是“需求追溯校验”:把生成的脚本逆解析回动作序列,和原始YAML比对。这个逆向翻译我会再调用一次LLM,让它“把pytest代码转回YAML”,然后对比两者的动作数、接口名、断言数量是否一致。如果逆向和正向不一致,说明生成走了样,直接打回。
人工确认环节只需要看两样东西:动作序列是否符合预期、断言强度是否足够。如果每条生成脚本都要人工逐行读代码,那提效就失败了。所以中间表示(YAML)存在的意义是把“审代码”变成“审表格”。我这里还有一个习惯:把人工确认后的YAML打上“已审核”标签,下次需求变更时只对比新旧YAML差异,而不是重新审查整条代码。这套流程跑下来,单条用例的人工介入时间从原来的二十分钟压缩到两分钟。
4. 通讯行业特有的五个调整点:协议、时序、专网、合规、数据
4.1 协议栈与编解码:不要让AI自己猜报文
通讯行业的端到端测试涉及SIP、Diameter、HTTP/2、MQTT、私有协议。AI模型对公共协议的理解不错,但对私有编解码一无所知。常见做法是:所有报文编解码函数都封装在测试框架的工具库里,提示词里只允许AI调用这些函数,禁止自己构造字节流。如果一定要让AI生成报文,则应提供ASN.1或TLV模板,让它填字段而不是凭空创造。
给提示词里加一条硬规则:“不得直接构造字节流,必须先调用 encode_XXX 方法。”这能避免大量字节错位问题。真实案例中,AI曾把Diameter的AVP长度字段计算错误,导致对端直接拒收消息。这类问题在脚本审查阶段很难肉眼发现,必须从源头掐断。我一般会把工具库的函数列表直接塞进系统提示词,并标注每个函数的参数和返回类型,AI能正确调用的概率会大幅提升。
4.2 时序与异步:把等待策略写进提示词
通信系统异步消息多,很多测试脚本挂在“等待响应”上。AI默认生成time.sleep(3),这是最粗糙的做法。要在提示词里明确:所有等待必须调用wait_until(predicate, timeout),并给出超时阈值偏好,比如默认5秒,信令流程最长15秒。同时告诉AI,不要在注册流程里用“软等待”替代“注册成功确认”,否则后续流程全乱。
这里有一个参数值得专门调:超时阈值。不同网元差异很大。核心网网元响应快,计费系统可能要等SSR回执,所以我会在YAML里给每个步骤配一个timeout字段,生成时把它传给wait_until。AI需要学会读这个配置,而不是自己拍脑袋。另外,凡是消息重传的场景,要在提示词里说明“最多重试三次、每次退避指数增长”,否则AI会把重传逻辑写成死循环。时序问题在通讯测试里是玄学重灾区,AI生成的脚本尤其容易在这里翻车。
4.3 专网与版本碎片化:模型需要看到“设备画像”
通讯厂商的产品线版本非常多,同一流程在V1.2和V2.0上的交互过程可能不同。通用AI模型不知道你们专网的版本差异。所以方案里要为被测环境建一个“设备画像”文件,包含网元型号、版本、协议能力、已知缺陷列表。生成脚本时把这个画像作为context塞进提示词,AI才会写出匹配版本的预期。
例如某个旧版本SBC不支持SIP INFO方法,AI如果不知道,就会生成一个实际跑不通的流程。设备画像的维护本身也可以交给AI:变更单来了,自动对比新旧版本差异,更新画像文件。这相当于让AI维护它自己的“记忆力”,是非常符合ai native研发范式的一步。注意,设备画像文件要按网元拆分,不要放在一个大文件里,否则提示词太长,模型会丢失注意力。我通常给每个网元一个Markdown文件,控制在五十行以内,只写关键差异,不写手册。
4.4 合规与安全:生成代码必须先过静态检查
通讯行业对测试代码没有太多合规要求,但一旦AI生成代码要进生产CI或接入现网数据,就必须做安全门禁。AI生成代码常见的风险:硬编码口令、使用不安全的加密库、把敏感数据打进日志。我们会在生成后自动跑一遍自定义规则和semgrep扫描。比如禁止出现用于连接现网的账密、禁止把用户号码打印到测试报告里、禁止调用未脱敏的配置文件读取接口。
如果你用多AI协作的方式,让一个Agent专门生成测试数据,另一个生成脚本,那么还需控制Agent之间的上下文权限。不要让数据生成Agent直接读生产库,给它的应该是脱敏的schema和字段约束。这个安全边界要在系统设计阶段就定好,不要指望提示词能约束住所有越权操作。我见过一个团队因为Agent擅自调用了生产环境查询接口,差点把在线用户的签约数据卷入测试流量,后来他们加了网关级权限校验才算拦住。
4.5 测试数据:用合成数据而不是生产数据
端到端测试离不开真实号码段、IMSI、SIP URI。生产数据涉及用户隐私,且环境里的数据状态会随线上变化,不适合作为测试基线。我建议用合成数据生成器:先定义号码段规则、签约模板、业务参数范围,然后让AI按规则生成符合协议的测试数据。这里AI不是“创造”数据,而是按你给的规则填充。例如“号码段取139XXXX0001-1000,APN为CMNET,IMEI符合Luhn校验”。
合成数据的最大坑是“生成得太假”——所有数据分布均匀,没有边界值和压力值。所以生成器里要掺入前缀碰撞、重复IMSI、超大字段值这类脏数据,用它们专门做鲁棒性测试。AI擅长按模板批量生成,但脏数据规则需要人来设置,不要指望它自己悟出来。我一般会在YAML数据模板里加一个data_strategy字段,可选值为normal、boundary、stress,这样每条测试数据都能说清楚它属于哪类策略,排查问题时一目了然。
5. 避坑指南:AI生成测试脚本的6个常见翻车现场
5.1 现象:AI生成的脚本“看起来对,跑起来废”
第一轮跑AI生成脚本时,经常遇到语法没问题、函数也都存在,但就是跑不通的情况。原因往往是AI对被测系统的隐含状态理解错误,例如它假设用户已注册,但实际上注册流程在另一个夹具里没触发,导致调用SIP方法时直接报“用户未注册”。解决:生成提示词里强制要求“必须注明每个前置条件的建立方式”,并且生成的脚本必须包含前置条件的setup代码或引用已有夹具。如果AI不写setup,就判为不合格。我在模板引擎里加了一个校验器,扫描生成的代码里是否有env.ue.register这类前置调用,没有的话直接打回重生成。
5.2 现象:提示词越加越长,效果反而变差
很多人在提示词里堆了三百行说明,结果AI开始“取巧”——总是生成和示例一模一样的模板,丧失了对具体需求的适配能力。这是因为模型注意力被过多示例分散了。解决:把提示词分层。第一层是系统提示,固定为业务规则;第二层是用户提示,放入具体需求和环境信息;第三层是少量示例,每个示例对应一种典型场景。示例不要超过5个,并且要刻意覆盖“正常、边界、异常”三类。如果遇到特别复杂的协议,不要试图用提示词讲完所有细节,而是把细节放进一个参考文档里,让AI“先读取文档再作答”。
5.3 现象:模型幻觉出根本不存在的接口字段
有一次生成IMS注册测试脚本,AI调用了不存在的SIP头字段P-Served-User,还给它赋了一个不存在的值。这类问题的根源是模型训练数据里的“通用电信知识”和你们设备的实际实现不一致。解决:给AI一个“接口字典”文件,列出所有可用方法和字段名,并在提示词里声明“只能使用字典里的接口”。同时生成后做一个字段校验:用静态脚本把生成的代码里所有方法名、字段名和字典做匹配,命不中的直接标红。相信我,这一步必不可少,能拦下80%的幻觉字段。接口字典需要随版本更新,建议放在版本控制里,和代码一起评审。
5.4 现象:多AI协作时,一个Agent改坏了另一个的状态
我试过用两个Agent,一个负责生成测试步骤,一个负责生成测试数据。数据Agent会自作聪明地修改“全局用户状态表”,导致步骤Agent拿到的用户状态和预期不符。解决:Agent之间不能直接共享可变状态,必须通过中间文件或消息队列传递不可变数据结构。更简单的方法是,每个Agent只做“读入输入,产出输出”,不做任何更新操作。状态变更统一由主控流程处理。这个模式和函数式编程的思路很像,虽然牺牲了一点“多AI协作”的灵活性,但换来的是可调试性和确定性。在通讯行业里,确定性比灵活性重要得多。
5.5 现象:生成速度很快,但维护成本被转移到“提示词”上
AI生成脚本后,需求一变,你不需要改代码了,但要改提示词。这看起来进步了,实际上如果每个需求都改提示词,维护成本并没有消失。解决:把“业务规则”和“场景描述”分离。业务规则(信令流程、协议约束)放到系统提示词里,长期不变;场景描述(本次要测什么)放到用户提示词里,按需求变化。这样改动点是压缩的。另外,每次提示词变更都应当有版本记录,我用git管理prompt文件,CI里跑一次回归,确保没打破旧脚本。如果你的团队还没有专门维护提示词的仓库,建议尽快建一个,否则半年后你会对着无人理解的旧提示词发呆。
5.6 现象:测试报告里AI写的断言全是弱断言
AI倾向于生成“响应码200”“消息已发送”这类弱断言,因为最容易通过。端到端测试的价值恰恰在于业务链路验证。解决:在规则里定义“弱断言清单”,生成后自动扫描,检查每条用例是否有至少一个业务断言。例如业务断言可以是“收到SDP且包含正确的媒体IP”“主被叫都进入通话态”。没有业务断言的用例直接打回重生成。自动扫描的实现很简单:用正则匹配断言语句,剔除只包含status、return、success的断言,统计剩余断言数。这个阈值根据用例复杂度调整,但至少保证有一条真·业务断言。
6. 从试点到落地:我建议这样定边界、做评估、逐步推广
6.1 先用“30个历史需求”做基线回归测试
选这个方案时,不要上来就拿新需求试点。更好的做法是选过去已完成的30个历史需求,这些需求有真实代码和真实结果。让AI重新生成一遍脚本,和原脚本做对拍。对拍时看三点:动作序列是否覆盖原脚本关键步骤、断言强度是否不弱于原脚本、执行通过率是否达到原脚本水平。30个需求足够暴露80%的生成模式问题,也足够你估算出真实的提效倍率。我当时跑完这30个需求,发现AI在“需求理解”上的成功率只有七成,但在“模板化脚本生成”上几乎能到九成,这直接决定了后续落地形态。
6.2 评估指标不要只看生成成功率
生成成功率(AI生成的脚本能直接运行的占比)是基础指标,但不是核心指标。核心指标是“脚本交付后一周内的人工修订次数”和“脚本上线后因脚本错误导致的误报率”。我见过团队把生成成功率从60%优化到90%,但修订成本仍然很高,因为AI把相同的错误模式复制到了每个脚本里。所以要统计“缺陷模式重复率”:同一个原因(比如总是用错等待函数)导致的失败出现多少次。这个指标才是AI提效的真相。建议用表格记录每一条失败的原因分类,每周回顾一次,把频次最高的三类原因写回提示词规则里。
6.3 让AI生成“测试设计”而不是“测试代码”的混合模式
到最后你会发现,完全由AI生成脚本,在通讯行业里很难保证质量。我目前的落地形态是“AI生成测试设计,人工写关键脚本”:即AI负责输出动作序列、预期结果、测试数据、边界场景表,测试工程师只需把设计表格里高风险的20%动作手动写脚本,剩下的交给模板生成。这个混合模式的好处是:人工介入减少,而安全边界清晰。AI在“设计”上比“写代码”更擅长,也更少产生幻觉。如果你预算有限,优先做需求解析和场景生成这两段,它们带来的提效比是最高的。
最后分享一个习惯:每次跑完AI生成的脚本,我会把失败日志和最终修订结果回喂给LLM,让它生成一份“修订原因摘要”并存入测试资产库。下次生成同类脚本时,这些摘要会被自动附加到提示词里。这个做法让AI的生成质量随着项目进行缓慢上升,而不是停留在同一个水平。这套方案和这些坑,希望能在你落地AI测试开发时少走几次弯路,希望帮到你。
本文还有配套的精品资源,点击获取