发布时间:2026/8/23 23:49:23
Agent用例生成进阶:从测试策略到Pytest代码 概述上一篇做了测试策略输入需求输出JSON。但CI流水线不认JSON它要的是pytest能跑的东西这篇就把测试策略转成Pytest代码。现在我们有策略策略里啥都有场景、预期、类型、优先级。把这些喂给AI需求进去代码出来中间不需要人动手。用例生成模块是做什么的输入测试策略JSON输出Pytest测试代码。具体点说输入是上一篇生成的策略功能名称、场景列表、步骤、预期结果。输出是一个完整的测试文件你拿过来就能用pytest命令跑。为什么要拆成两步把意图理解和用例生成合并成一步输入需求直接输出Pytest代码。听起来很爽少了一道工序但合在一起真的不好用。可能带来的问题出错了你找不到原因生成的代码挂了你不知道是需求理解错了还是代码生成环节出了岔子。日志里只有头和尾中间发生了什么是个黑盒。你想改没地方下手。策略生成错了你想手动改一下再重新生成。如果合并成一步你得重新跑一遍完整流程API费用再花一次。换个框架你得重写全部。同一个测试策略你可能想生成pytest版本的也可能想生成unittest版本的合并的话每种框架你得维护一套完整逻辑。拆开的话策略模块不用动只换生成模块就行。所以拆开更实用具体怎么做3.1 核心实现先写一个生成器类。# test_generation.pyimportjsonimportosfrompathlibimportPathfromtypingimportDict,Optionalfromdotenvimportload_dotenvfromopenaiimportOpenAIclassTestGenerationAgent: 用例生成Agent。 输入测试策略JSON和源代码输出Pytest测试代码。 def__init__(self,model:strgpt-4o):load_dotenv()self.clientOpenAI(api_keyos.getenv(OPENAI_API_KEY),base_urlos.getenv(OPENAI_BASE_URL,None))self.modelmodeldefgenerate(self,strategy:Dict,source_code:str,module_name:strapp)-str:根据测试策略和源代码生成Pytest测试代码。promptself._build_prompt(strategy,source_code,module_name)try:responseself.client.chat.completions.create(modelself.model,messages[{role:system,content:self._get_system_prompt()},{role:user,content:prompt}],temperature0.3)returnresponse.choices[0].message.contentexceptExceptionase:print(f用例生成失败:{e})returndef_get_system_prompt(self)-str:return 你是一位资深的测试开发工程师擅长用Pytest编写高质量的单元测试。 你的任务是根据提供的测试策略和源代码生成完整的Pytest测试代码。 要求 1. 测试代码必须覆盖策略中定义的所有场景 2. 使用pytest框架遵循最佳实践 3. 每个测试场景对应一个测试方法 4. 方法名用test_开头后面跟场景的英文标识 5. 使用pytest.raises处理异常场景 6. 添加适当的注释说明每个测试的用途 7. 代码风格清晰、规范 8. 只输出Python代码不要额外解释 def_build_prompt(self,strategy:Dict,source_code:str,module_name:str)-str:scenariosstrategy.get(test_scenarios,[])scenario_textjson.dumps(scenarios,indent2,ensure_asciiFalse)returnf#下面是待测试的源代码{source_code}#下面是测试策略包含需要覆盖的测试场景{scenario_text}# 请为 {module_name} 模块生成完整的Pytest测试代码。defsave_test_code(code:str,filepath:strtest_generated.py):withopen(filepath,w,encodingutf-8)asf:f.write(code)print(f测试代码已保存:{filepath})3.2 如何使用加载上一篇生成的测试策略传入源代码调用生成器。if__name____main__:# 加载上一篇生成的测试策略withopen(login_strategy.json,r,encodingutf-8)asf:strategyjson.load(f)# 被测试的源代码source_code # login.py class UserService: def __init__(self): self._users { 13800001111: {password: 123456, nickname: 张三, locked: False}, testexample.com: {password: 123456, nickname: 李四, locked: False}, } self._login_attempts {} self._locked_accounts {} def login(self, account: str, password: str) - dict: if account not in self._users: return {success: False, message: 账号不存在} user self._users[account] if user.get(locked, False): return {success: False, message: 账号已被锁定请联系客服} if account in self._locked_accounts: lock_time self._locked_accounts[account] if lock_time 0: return {success: False, message: 账号已被锁定30分钟} if user[password] ! password: self._login_attempts[account] self._login_attempts.get(account, 0) 1 if self._login_attempts[account] 5: self._locked_accounts[account] 30 return {success: False, message: 因多次登录失败账号已被锁定30分钟} return {success: False, message: 密码错误} self._login_attempts[account] 0 return { success: True, message: 登录成功, nickname: user[nickname] } agentTestGenerationAgent()test_codeagent.generate(strategy,source_code,login)iftest_code:save_test_code(test_code,test_login.py)print(\n生成的测试代码\n)print(test_code)else:print(生成失败)3.3 AI生成的代码运行上面的脚本test_login.py的内容大概是这样的。# test_login.pyimportpytestfromloginimportUserServiceclassTestUserLogin:用户登录功能的测试套件defsetup_method(self):每个测试方法执行前重置状态self.serviceUserService()deftest_login_with_phone_success(self):TC-001: 使用手机号正确登录resultself.service.login(13800001111,123456)assertresult[success]isTrueassertresult[message]登录成功assertresult[nickname]张三deftest_login_with_email_success(self):TC-002: 使用邮箱正确登录resultself.service.login(testexample.com,123456)assertresult[success]isTrueassertresult[message]登录成功assertresult[nickname]李四deftest_login_account_not_exist(self):TC-003: 登录失败-账号不存在resultself.service.login(13900001111,123456)assertresult[success]isFalseassertresult[message]账号不存在deftest_login_wrong_password(self):TC-004: 登录失败-密码错误resultself.service.login(13800001111,wrongpass)assertresult[success]isFalseassertresult[message]密码错误deftest_login_account_locked_by_admin(self):TC-005: 登录失败-账号被锁定self.service._users[13800001111][locked]Trueresultself.service.login(13800001111,123456)assertresult[success]isFalseassertresult[message]账号已被锁定请联系客服deftest_login_trigger_lock_after_5_failures(self):TC-006: 连续输错密码触发锁定account13800001111foriinrange(5):resultself.service.login(account,wrongpass)ifi4:assertresult[message]密码错误else:assertresult[message]因多次登录失败账号已被锁定30分钟assertresult[success]isFalsedeftest_login_paste_disabled(self):TC-007: 密码框禁止粘贴# 这个场景是前端约束单元测试测不了# 实际项目中需要UI自动化测试覆盖pytest.skip(前端约束需要UI自动化测试验证)deftest_login_response_time(self):TC-008: 登录接口响应时间importtime starttime.time()self.service.login(13800001111,123456)elapsed(time.time()-start)*1000assertelapsed500,f响应时间{elapsed}ms超过500ms策略里的8个场景变成了8个测试方法。每个方法对应一个场景断言也写好了。3.3 把两步串起来下面这个脚本把意图理解和用例生成串成一条线。# end_to_end.pyimportjsonfromintent_understandingimportIntentUnderstandingAgentfromtest_generationimportTestGenerationAgentdefrun_end_to_end(requirement:str,source_code:str,module_name:strapp):print(*50)print(Step 1: 意图理解)print(*50)intent_agentIntentUnderstandingAgent()strategyintent_agent.understand(requirement)iferrorinstrategy:print(f失败:{strategy[error]})returnprint(f生成{len(strategy.get(test_scenarios,[]))}个场景)withopen(strategy_output.json,w,encodingutf-8)asf:json.dump(strategy,f,indent2,ensure_asciiFalse)print(策略已保存: strategy_output.json)print(\n*50)print(Step 2: 用例生成)print(*50)gen_agentTestGenerationAgent()test_codegen_agent.generate(strategy,source_code,module_name)ifnottest_code:print(生成失败)returnwithopen(test_output.py,w,encodingutf-8)asf:f.write(test_code)print(测试代码已保存: test_output.py)print(\n*50)print(完成)print(*50)print(f场景数:{len(strategy.get(test_scenarios,[]))})print(下一步: pytest test_output.py -v)if__name____main__:requirement 需求用户登录功能 用户可以使用手机号或邮箱进行登录。 登录时需要验证密码是否正确。 登录成功后的行为 - 跳转到个人主页 - 在顶部显示用户昵称 登录失败的场景 - 手机号/邮箱不存在提示账号不存在 - 密码错误提示密码错误 - 账号被锁定提示账号已被锁定请联系客服 安全要求 - 连续输错5次密码后账号锁定30分钟 source_code class UserService: def __init__(self): self._users { 13800001111: {password: 123456, nickname: 张三, locked: False}, } self._login_attempts {} self._locked_accounts {} def login(self, account: str, password: str) - dict: if account not in self._users: return {success: False, message: 账号不存在} user self._users[account] if user.get(locked, False): return {success: False, message: 账号已被锁定请联系客服} if account in self._locked_accounts: return {success: False, message: 账号已被锁定30分钟} if user[password] ! password: self._login_attempts[account] self._login_attempts.get(account, 0) 1 if self._login_attempts[account] 5: self._locked_accounts[account] 30 return {success: False, message: 因多次登录失败账号已被锁定30分钟} return {success: False, message: 密码错误} self._login_attempts[account] 0 return {success: True, message: 登录成功, nickname: user[nickname]} run_end_to_end(requirement,source_code,login)跑完之后执行pytest test_output.py-v看到测试通过的那一刻整个流程就闭环了。需求进去代码出来中间不用你写一行。常见问题Q1生成的代码能直接用吗最好检查一遍。AI偶尔会犯错。import路径不对或者依赖的类名写错了。大问题不多小毛病难免。但比自己从头写还是能省了至少一个小时的时间Q2代码跑不通怎么办把报错信息贴给AI让它自己改。这是目前最省事的做法。把pytest的输出复制下来跟原始代码一起发给AI告诉它这段测试挂了帮我修一下。大部分情况下AI能自己搞定。Q3场景太多了生成慢怎么办拆成几批。如果一个策略有20多个场景你可以分两批生成。先让AI生成前10个保存。再生成后10个追加到同一个文件。这样每次请求的数据量小一些响应快也不容易超出AI的上下文窗口。Q4项目代码风格不一样怎么办把规范写进prompt里。比如你们项目要求测试类必须继承某个基类或者必须用特定的fixture。把这些要求写进系统提示词AI会照着做。如果你想做得更细致可以在项目里放一个规范文件每次生成之前让AI先读一遍。总结意图理解管出策略用例生成出代码中间用JSON对接。整个流程是这样的需求描述 → 测试策略 → Pytest代码 → pytest执行前三步我们已经能自动跑通了第四步就是pytest自己的事。

相关新闻

2026/8/23 23:49:23

C++函数指针语法和类型

函数指针是 C/C 中一种将函数地址作为变量存储和传递的机制,它允许程序在运行时动态选择并调用不同的函数,是实现回调、策略模式和插件系统的核心基础。核心语法结构函数指针的声明语法遵循“返回类型 (*指针名)(参数列表)”的格式。例如,声明…

2026/8/23 23:49:23

Go服务生产环境的生存规则,你知道几条?

Go 让你很容易就能写出一段“能编译、能通过冒烟测试、一遇到真实流量就跪”的代码。这门语言默认给你很少——没有运行时异常可以捕获,没有框架护栏,没有魔法。这是个特性,但这也意味着:让一个服务在生产环境活下去的规则&#x…

2026/8/23 23:49:23

Open-Connector:开源连接器网关,解决AI Agent接入SaaS服务难题

【导语:Open-Connector作为面向AI Agent和应用开发者的开源连接器网关,旨在解决AI Agent接入外部SaaS服务的系列问题,提供丰富的连接器目录和预构建Actions,适用于多种类型项目。】开源网关解决AI Agent接入难题Open-Connector是一…

2026/8/23 23:59:23

优选乡墅赋能培训课程包含哪些内容,有什么作用?

优选乡墅赋能培训课程能助力学员掌握乡墅业务各环节知识与技能,湖北乡墅研究中心的课程体系完善,涵盖多方面内容。知识保障湖北乡墅研究中心提供运营标准赋能体系整套SOP全部手册,为学员提供全面、系统的理论知识依据。这些手册详细记录乡墅业…

2026/8/23 23:59:23

论文AI率过高怎么办?2026年12款免费降AI率工具实测指南

现在毕业论文答辩前,“AI率超标”已经彻底取代“查重率过高”,成了同学们的头号难题!不少同学只是用AI润色了摘要和结论,AI率直接飙升到离谱,纯手动修改根本不管用——这说明AIGC检测系统抓的不是个别词语,…

2026/8/23 23:59:23

Marketch:从Sketch画板直接量取CSS

Marketch:从Sketch画板直接量取CSS 【免费下载链接】marketch Marketch is a Sketch 3 plug-in for automatically generating html page that can measure and get CSS styles on it. 项目地址: https://gitcode.com/gh_mirrors/ma/marketch 设计稿交付还在…

2026/8/23 23:59:23

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南 【免费下载链接】ThinkpadX390-Opencore-EFI macOS Catalina & Big Sur & Monterey on ThinkPad X390 (Hackintosh) 项目地址: https://gitcode.com/gh_mirrors/th/ThinkpadX390-Opencore-EFI …

2026/8/24 0:07:22

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:02:04

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:02:04

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 13:29:45

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/23 6:14:43

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/23 4:22:01

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…