大数跨境

从一句话到可运行用例:AI自动化用例生成Agent实战

从一句话到可运行用例:AI自动化用例生成Agent实战 51Testing软件测试网
2026-11-03
4
导读:一句话描述测试目标,AI自动化用例生成Agent结合UI dump自动产出pytest+Poco规范用例,经校验、预览、写入闭环,低token高提效。
前言:测试工程师为什么需要这个Agent?

很多人第一次接触 Android UI 自动化测试时,都会卡在:Airtest 装好了,Poco 也能连上,pytest 框架目录也摆在那里,可真正要写第一条用例时,反而不知道从哪里开始。

比如说,我们想测试下app的某个按钮能不能点击,这对于人类而言很直观,但脚本还要知道:页面有没有目标节点?它在 Poco 树里叫什么?点击前是否等待?常量放到哪个目录?

如果每个测试点都靠人工打开 UI 树、复制字段、手写 locators.py 和 test_xxx.py,自动化测试很快就会变成负担。

AI 自动化用例生成器正是为了解决这个问题而设计的:用自然语言描述测试目标,结合当前页面 UI dump,自动生成符合项目约定的 pytest + Poco 用例和页面元素文件。

这个Agent的核心优势在于效率和成本控制:

• 极低的 token 消耗:相比直接让 AI 助手基于完整对话上下文生成用例,本Agent采用精简的提示词设计,每次生成只传递必要的测试目标、页面名称和 UI dump 信息,单次调用通常只需数千 tokens,而不是动辄几万甚至十几万 tokens 的上下文开销。这对于需要批量生成用例的团队来说,能大幅降低 API 调用成本。
• 显著的提效表现:传统手写一条用例可能需要 20-30 分钟(查看 UI 树、确认定位、编写代码、调试运行),使用生成器后,从需求描述到可运行代码通常只需 2-3 分钟,提效 10 倍以上。更重要的是,生成的代码直接符合项目规范,减少了代码评审和重构的时间。
• 可预测的质量保障:Agent内置了代码校验、路径规范化和提示词约束,确保每次生成的结果都遵循统一标准。不会出现 AI 自由发挥导致的封装不一致、导入路径混乱或无法运行的问题。

这篇文章会带你从零理解并使用 AI 自动化用例生成器,走完生成预览、写入文件、运行用例、排查失败的闭环。

一、AI 自动化用例生成器的核心价值

App UI 自动化测试用例生成器,能把一句测试需求转换成项目内可维护的 Python 测试代码。

它连接了三类信息:你输入的测试目标、Poco 导出的当前页面 UI dump、项目已有的 pytest + Poco 自动化框架。传统写用例的流程一般是:

使用 AI 自动化用例生成器 后,流程变成:

这里有一个重要思想:AI 负责生成,程序负责约束。模型不是随意发挥,而是在提示词、路径规则、AST 校验和写入策略的保护下工作。

二、它在项目中的位置

脚本路径是:


agent_client/write_cases.py

默认生成的用例文件位于 app_ui_tests/cases/test_generated.py,默认生成的页面元素文件位于 app_ui_tests/pages/<page>/elements/locators.py。

用例文件负责表达测试步骤,元素文件负责保存定位常量。比如用例里写:


from app_ui_tests.pages.apidemos_home.elements.locators import VIEWS_TEXT, TEXTVIEW_TYPE
 
def test_click_views(poco):
views_button = poco(text=VIEWS_TEXT, type=TEXTVIEW_TYPE)
views_button.wait_for_appearance(timeout=10)
assert views_button.exists(), "ApiDemos 主页未找到 Views 按钮"
views_button.click()

定位值则放在 locators.py 中:


VIEWS_TEXT = "Views"
TEXTVIEW_TYPE = "android.widget.TextView"

这种拆分对维护很有帮助:页面节点变更时优先修改元素文件,同一页面新增用例时也能复用定位常量。

三、运行前准备:模型、设备和 UI dump

使用这个Agent前,先准备三件事。

第一,项目依赖要安装完成:


python -m pip install -r requirements.txt

第二,根目录 .env 中要配置模型信息:


OPENAI_API_KEY=your_api_key_here
OPENAI_BASE_URL=https://api.example.com
OPENAI_MODEL=your_model_name
OPENAI_DISABLE_TRACING=true

AI 自动化用例生成器会通过 load_dotenv(PROJECT_ROOT / ".env") 读取配置。如果缺少 OPENAI_API_KEY 或 OPENAI_BASE_URL,脚本会直接报中文错误,提醒你先补配置。

第三,设备和页面要准备好。因为脚本生成用例时会参考当前页面 UI dump,所以你最好先把 App 停留在目标页面。默认 UI dump 路径是app_ui_tests/artifacts/script_outputs/visible_ui.txt,刷新脚本是app_ui_tests/scripts/dump_poco_ui.py。

如果你想手动导出,也可以运行:


python app_ui_tests/scripts/dump_poco_ui.py

只导出可点击节点:


python app_ui_tests/scripts/dump_poco_ui.py --only-clickable

如果已经有现成的 dump 文件,不希望脚本重新连设备刷新,可以加:


--no-refresh-ui

例如:


python agent_client/write_cases.py 点击"App"文案 --ui-dump ./visible_ui.txt --no-refresh-ui

这里特别建议测试工程师把 UI dump 当成页面地图来看。自动化脚本并不是凭感觉点击,它需要从这张地图里找到一个稳定入口。

地图里通常会出现节点名称、控件类型、显示文本、位置、尺寸、是否可点击等信息。

你不需要一开始理解所有字段,但至少要学会找三个东西:目标元素的名称、目标元素的类型、目标元素周围有没有能辅助定位的父节点。

父节点之所以重要,是因为很多 App,尤其是列表页面,会出现大量同名节点。页面上可能有很多 TextView、很多 LinearLayout。

如果只让脚本找第一个文本或第一个容器,它很可能点到错误位置。更稳的思路是先限定一个区域,再在这个区域里找目标元素。

比如先找到菜单列表容器,再找 Animation 选项;先找到顶部标题栏,再找标题文本。

AI 自动化用例生成器的提示词允许模型生成链式查询,正是为了处理这种同名节点很多的场景。

所以,生成用例前最好先让目标页面稳定显示。不要在加载动画刚出现时导出 UI dump,也不要在弹窗遮挡页面时生成普通页面用例。

UI dump 是某一瞬间的快照,快照越准确,生成结果越可靠。如果页面还没稳定,模型拿到的就是一张抖动的地图,后面生成的脚本自然容易失败。

四、第一次生成:先预览,不急着写文件

最简单的使用方式是:


python agent_client/write_cases.py 点击ApiDemos主页的"Content"文案

注意,默认情况下它不会写入文件,只会在终端预览生成结果。这个设计非常适合新手,因为你可以先确认模型是否选对元素、用例命名是否清晰、断言是否合理,然后再决定是否落盘。

一次预览会经历这些步骤:

• 读取 .env。
• 解析命令行参数。
• 刷新或读取 UI dump。
• 推导用例输出路径。
• 推导页面元素路径。
• 构造提示词并调用模型。
• 解析模型返回的 JSON。
• 校验 elements_code 和 test_code。
• 打印预览内容。

预览结果一般包含页面元素代码和测试用例代码两段。如果你觉得生成结果合理,再加 --write 写入文件:


python agent_client/write_cases.py 点击ApiDemos主页的"Content"文案 --write

预览阶段不要只看代码有没有生成,还要像做代码评审一样看它是否符合测试意图。

  • 第一,看测试函数名,函数名应该能说明这个用例测什么。

  • 第二,看导入路径,确认它导入的是你期望的页面元素目录。

  • 第三,看定位器,确认常量值确实来自当前 UI dump,而不是模型根据文字猜出来的。

  • 第四,看断言文案,失败时你能不能通过报错知道哪个页面、哪个元素出了问题。

对测试工程师来说,预览还有一个学习价值:你可以把自然语言需求和生成代码一一对应起来。

比如你输入“点击 Views 按钮”,模型生成了 views_button = poco(text=VIEWS_TEXT, type=TEXTVIEW_TYPE),你就能理解 Poco 查询和页面元素常量之间的关系。多看几次预览,你会逐渐知道怎样描述需求更容易生成好代码。

我们执行一下这条用例:

测试通过了,页面成功跳转:

五、指定页面和文件:让生成结果更可维护

真实项目里,不建议所有用例都写到 test_generated.py。更好的方式是按页面或业务模块命名。

例如 ApiDemos 主页:


python agent_client/write_cases.py 验证主页菜单项可见 --page ApiDemos主页 --page-dir apidemos_home --output test_apidemos_home.py --write

这里有三个关键参数:


--page ApiDemos主页

这是给模型看的页面名称,帮助它理解业务场景。


--page-dir apidemos_home

这是页面元素目录名,最终会生成:


app_ui_tests/pages/apidemos_home/elements/locators.py

--output test_apidemos_home.py

这是测试用例文件名,最终会生成:


app_ui_tests/cases/test_apidemos_home.py

如果没有传 --page-dir,脚本会从输出文件名推导页面目录。比如 test_apidemos_home.py 会推导出 apidemos_home。

源码中对应逻辑是先取文件 stem,去掉开头的 test_,再调用 normalize_module_name() 转成合法模块名。

实践建议是:中文页面名给模型看,英文目录名给 Python 用。比如:


python agent_client/write_cases.py 点击Views按钮 --page ApiDemos主页 --page-dir apidemos_home --output test_apidemos_home.py

这样既能保留业务语义,又能保证 import 路径稳定。

还有一个容易忽略的小习惯:--output 最好按测试主题命名,不要长期使用默认的 test_generated.py。默认文件适合试验,但不适合沉淀。

比如主页相关用例放到 test_apidemos_home.py,Views 页面相关用例放到 test_views.py,Animation 页面相关用例放到 test_animation.py。当用例数量多起来后,这种命名会直接影响排查效率。

--page-dir 也建议保持稳定。不要今天叫 apidemos_home,明天叫 home,后天又叫 main_page。页面目录名一旦变化,import 路径就会变化,后续维护成本会增加。

对团队来说,可以先约定一张页面目录表,把常用页面的中文名和英文目录名固定下来。

六、追加模式:在已有页面上继续积累用例

一个页面通常会有多条用例。ApiDemos 主页可能要测 App、Views、Animation、Graphics 等多个菜单项入口。此时应该使用追加模式,而不是每次覆盖旧文件。

命令示例:


python agent_client/write_cases.py 检查主页Animation按钮可见 --page ApiDemos主页 --page-dir apidemos_home --output test_apidemos_home.py --write --append

追加模式会把新生成的测试函数追加到已有用例文件末尾,也会把新生成的定位常量追加到已有 locators.py 末尾。

源码里还会自动移除追加片段中的 from __future__ import ... 和重复的 import pytest,避免 future import 出现在文件中间,也避免 import 越堆越乱。

追加完成前,脚本会对拼接后的完整代码再次执行 ast.parse()。这意味着语法错误会在写入前被发现,避免把坏代码塞进项目。

七、提示词设计:让模型生成项目需要的代码

AI 自动化用例生成器 最值得学习的地方,是它没有简单地对模型说帮我写个测试脚本,而是用 build_prompt() 把项目约定完整告诉模型。

提示词里包含四类信息:测试目标、页面名称、可见 UI 节点和项目约定。前三类让模型知道要做什么和当前页面有什么,第四类则决定代码能否融入项目。它要求模型遵守这些规则:

• 页面元素定义放在 app_ui_tests/pages/<page>/elements/locators.py。
• 用例文件放在 app_ui_tests/cases/ 下。
• pytest fixture 已经提供 poco,不要自己初始化 Poco。
• 页面元素文件只定义字符串常量。
• 测试用例必须从页面元素文件导入常量。
• 测试步骤必须使用 Poco 原生写法。
• 不要生成 poco(**LOCATOR)。
• 不要生成 get_node()、click()、assert_exists() 这类未定义封装。
• 测试函数名必须以 test_ 开头。
• 点击前先等待元素出现,并用断言给出清晰失败原因。

这些约束的作用,是把模型输出拉回本项目真实可运行的范围。AI 很容易生成看起来漂亮但项目里不存在的封装函数,例如 click("导航") 或 assert_exists("二级页面")。

如果项目没有这些函数,代码就无法运行。提示词明确要求使用 Poco 原生方法:


node = poco(text=VIEWS_TEXT, resourceId=VIEWS_RESOURCE_ID)
node.wait_for_appearance(timeout=10)
assert node.exists(), "未找到 Views 按钮"
node.click()

这类代码更直接,也更适合初学者理解。

模型生成代码时,最怕输出格式不稳定。有时它会写说明文字,有时会写 Markdown 代码块,有时会把两个文件混在一起。

为了让脚本能自动处理,AI 自动化用例生成器 要求模型只输出包含 elements_code 和 test_code 的 JSON 对象。

如果模型把 JSON 包在 Markdown 代码块里,extract_json_text() 也会尝试提取代码块内容。最终目标仍然是稳定 JSON,因为只有结构化输出才能进入后续校验和写入流程。

这里可以学到一个通用经验:让 AI 参与工程流程时,不要只写帮我生成,而要把输出边界写清楚。

边界越清楚,自动化程度越高。AI 自动化用例生成器的提示词同时规定了目录、导入方式、定位器形态、Poco 写法、测试函数命名、注释位置和 JSON 格式,所以后面的 Python 代码才能放心解析和校验。

如果以后你想扩展这个Agent,也应该优先改提示词里的项目约定,而不是一开始就改很多生成后处理逻辑。

比如团队决定所有冒烟用例都必须加 pytest.mark.smoke,可以在提示词中强调;团队决定导航类用例不要写死属性值,也可以在提示词中加入规则。

提示词是模型的轨道,轨道铺得越清楚,生成结果越少跑偏。

......

本文节选自第九十二期《51测试天地》原创文章

《从一句话到可运行用例:AI自动化用例生成Agent实战》

文章后续为大家详细讲解了:
约束模型输出、代码校验和实战问题等

想继续阅读全文

或查看更多《51测试天地》的原创文章

请点击下方 阅读原文或扫描二维码 查看

图片

声明:本文为51Testing软件测试网 blues_C 用户投稿内容,该用户投稿时已经承诺独立承担涉及知识产权的相关法律责任,并且已经向51Testing承诺此文并无抄袭内容。发布本文的用途仅仅为学习交流,不做任何商用,未经授权请勿转载,否则作者和51Testing有权追究责任。如果您发现本公众号中有涉嫌抄袭的内容,欢迎发送邮件至:editor@51testing.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

【声明】内容源于网络
0
0
51Testing软件测试网
博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
内容 3989
粉丝 0
51Testing软件测试网 博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
总阅读7.2k
粉丝0
内容4.0k