尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
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自己的事。
RELATED

相关推荐

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

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

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

📅 2026/10/16 18:20:20
Go服务生产环境的生存规则,你知道几条?

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

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

📅 2026/9/25 9:43:57
Open-Connector:开源连接器网关,解决AI Agent接入SaaS服务难题

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

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

📅 2026/9/25 11:08:25
MORE NEWS

更多资讯

📰

青田低压电工证含金量高吗?中小施工企业负责人必看指南

青田低压电工证含金量高吗?中小施工企业负责人必看指南 你是不是正在找电工工作,但因为没有【青田低压电工证】而被拒之门外?别急,今天这篇内容,就帮你从零到一搞懂这个证书的 含金量…

📰

衡东办电工证千万别踩坑,转岗从业者这样报名才靠谱

衡东办电工证千万别踩坑,转岗从业者这样报名才靠谱 不知道去哪报名怕被中介坑,这事儿在特种作业证书办理圈里太常见了。尤其是像【衡东办电工证】这种热门项目,中介太多、信息太杂,一不小心就掉进坑里。今天我以漯河转岗从业者的亲身经历,给你讲讲怎么避…

📰

巴南区考电工证报名全攻略:学历不高怕报不上名?考前押题帮你过

巴南区考电工证报名全攻略:学历不高怕报不上名?考前押题帮你过 你是不是也觉得学历不高,担心自己连电工证都考不上?别急,今天我就用一个真实案例,手把手教你如何在巴南区顺利考取电工证,哪怕你不是名校毕业,也能用对方法,轻松拿下证书。别再说“学历…

📰

电工证办理网络怎么补办?工地太忙根本没时间复习考试通过率揭秘

电工证办理网络怎么补办?工地太忙根本没时间复习考试通过率揭秘 工地太忙根本没时间复习考试,这几乎是所有一线电工的共同痛点。特别是在河南,像你这样刚毕业的工程类大学生,刚进工地就面临电工证补办、考试、甚至继续教育的问题,时间紧张、任务繁重、考…

📰

青田低压电工证值不值得考?学历不高怕报不上名?别慌,看完这篇就懂了

青田低压电工证值不值得考?学历不高怕报不上名?别慌,看完这篇就懂了 你是不是也这样?听说要考个【青田低压电工证】才能上岗,可自己文化程度不高,心里直打鼓:这玩意儿真的好考吗?值不值得花时间去考?别急,今天咱们就来聊聊这个话题,用最真实、最接…

📰

茂名电工证复审资料官方回应:实操考试心里没底怕挂科怎么破?

茂名电工证复审资料官方回应:实操考试心里没底怕挂科怎么破? 实操考试心里没底怕挂科,这是很多电工在复审和考试前最怕遇到的问题。尤其是在茂名,电工证复审资料的准备和考试流程相对复杂,很多人因为资料不全、流程不清,导致考试屡屡受挫,甚至被取消考…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬