AI赋能UI自动化测试:基于Weditor与LLM的智能脚本生成与优化实践

发布时间:2026/6/30 18:42:36
AI赋能UI自动化测试:基于Weditor与LLM的智能脚本生成与优化实践 1. 项目概述当AI遇见UI自动化测试最近在搞UI自动化测试的朋友估计都听过或者用过weditor这个工具。它本质上是一个基于Python的Web UI元素定位和调试工具可以看作是uiautomator2的“增强版浏览器”让你能像在Chrome DevTools里检查网页一样去查看和定位安卓App里的控件。这玩意儿本身已经大大提升了写自动化脚本的效率不用再对着adb shell uiautomator dump出来的那一大坨XML文件头疼了。但今天我想聊的不是weditor本身怎么用而是当它和现在火得不行的AI大模型结合后能碰撞出什么样的火花。简单说就是用AI来辅助我们完成从元素定位、脚本生成到异常处理的全流程。这听起来可能有点“未来已来”的感觉但实际上一些基础的结合点我们现在就能上手并且能实实在在地提升效率。传统的UI自动化测试尤其是移动端有几个老生常谈的痛点元素定位不稳定今天能抓到明天App一更新就抓瞎了、脚本编写枯燥重复大量的find_element、click、send_keys、异常处理繁琐需要写大量的try...except和等待逻辑。而AI特别是具备代码理解和生成能力的LLM恰好能在这些环节提供辅助。weditor提供了清晰的UI层级和属性信息这成为了AI“理解”当前界面的绝佳输入。我们可以把weditor捕获的页面结构比如控件的resource-id、text、bounds等信息喂给AI让它来帮我们生成稳定可靠的定位策略甚至是完整的操作脚本。这不仅仅是“用AI写代码”那么简单。它更像是一个AI增强的测试开发工作流。你从一个被动的脚本编写者变成了一个流程的设计者和审核者。AI负责处理那些模式固定、逻辑简单的部分而你则专注于业务逻辑校验、复杂场景设计和AI输出的质量把关。接下来我会结合具体的操作拆解如何搭建这样一个“AI辅助的weditor自动化测试”环境并分享其中几个关键环节的实战心得。2. 环境搭建与核心工具链选型要玩转AI辅助的自动化测试首先得把基础环境搭好。这里面的工具选型直接决定了后续流程的顺畅度。2.1 核心三件套Python、Weditor与设备连接基础中的基础依然是Python环境。建议使用Python 3.8或以上版本稳定性比较好。包管理方面pip足够但为了环境干净我强烈推荐使用venv或者conda创建一个独立的虚拟环境。# 创建虚拟环境 python -m venv ai-test-env # 激活环境 (Windows) ai-test-env\Scripts\activate # 激活环境 (Mac/Linux) source ai-test-env/bin/activate接下来安装weditor及其依赖的核心——uiautomator2。这里有个小细节直接pip install weditor会安装比较旧的版本。我更喜欢从GitHub安装最新版因为修复和功能更新更及时。# 安装uiautomator2 pip install -U uiautomator2 # 从GitHub仓库安装最新版weditor pip install -U githttps://github.com/openatx/weditor.git安装完成后在命令行输入weditor会自动打开浏览器默认http://localhost:17310并启动服务。此时你需要确保有一台安卓设备通过USB连接到电脑并开启了USB调试模式。在weditor的网页界面中点击连接设备如果一切正常你就能实时看到设备的屏幕镜像和完整的UI层级树了。这一步是后续所有操作的基石务必确保连接稳定。注意有时weditor无法连接设备可能是adb端口冲突或设备未授权。可以尝试adb kill-server然后adb start-server重启服务并在设备上确认“允许USB调试”的弹窗。2.2 AI编程助手的选择与配置这是本次体验的核心。我们需要一个能理解我们指令、能编写和修改Python代码的AI助手。目前市面上可选的产品很多比如Cursor、通义灵码、GitHub Copilot等。它们各有侧重我的选择逻辑如下Cursor后起之秀核心卖点是深度集成AI背后是GPT-4对代码上下文的理解能力极强特别适合在已有的测试项目中进行代码补全、重构和生成。它的“Chat”模式可以直接对话让它基于当前文件或项目生成代码非常贴合我们“辅助开发”的场景。通义灵码阿里云对中文语境和阿里系技术栈如Spring的支持可能更好同样具备代码补全、注释生成、单元测试生成等功能。GitHub Copilot老牌选手代码补全的“直觉”非常准但在复杂的、需要结合特定工具如weditor输出进行代码生成的场景下有时不如Cursor的聊天交互模式直接。我个人的主力选择是Cursor。原因很简单我们需要频繁地将weditor捕获的UI元素信息作为“提示词”的一部分发送给AI并要求它生成或修改对应的自动化代码。Cursor的聊天界面就像一个随时待命的资深测试开发工程师我可以直接把XML节点信息、甚至截图结合OCR丢给它用自然语言描述我的操作意图它就能给出非常可用的代码片段。配置Cursor很简单下载安装后关联你的IDE它本身基于VS Code或者直接使用它。最关键的一步是配置网络由于合规要求此处不展开任何具体工具或方法描述请确保在合法合规的前提下使用AI服务。确保Cursor能稳定访问其AI服务这是它工作的前提。然后在你的测试项目根目录用Cursor打开它就能基于整个项目的上下文为你提供帮助了。2.3 辅助工具让信息流转更顺畅仅有weditor和Cursor还不够我们需要一些“粘合剂”工具。截图与OCR工具weditor主要提供元素属性但有时AI需要“看到”界面。我们可以用uiautomator2自带的截图功能或者使用adb screencap。截取的图片如果需要提取文字信息给AI可以搭配开源的OCR库如paddleocr或easyocr。这主要用于辅助AI理解那些text属性为空但实际有文字的图片按钮或复杂控件。# 使用uiautomator2截图示例 import uiautomator2 as u2 d u2.connect() d.screenshot(“current_screen.png”)剪贴板管理工具这是一个提升效率的神器。我们需要频繁地在weditor浏览器、代码编辑器、Cursor聊天窗口之间复制粘贴元素属性。一个能记录历史剪贴板的工具如macOS的Alfred、Windows的Ditto能让你快速找回之前复制过的resource-id或xpath避免来回切换窗口。结构化提示词模板在多次与AI交互后我发现准备一个清晰的提示词模板至关重要。不要每次都说“帮我写个点击代码”。而是应该提供一个结构化上下文比如“我正在编写安卓App的UI自动化测试脚本使用的是Python的uiautomator2库。当前通过weditor抓取到的目标控件信息如下resource-id: com.example.app:id/login_buttontext: “登录”class: android.widget.Buttonbounds: [360, 1200][720, 1300]请为我生成一个最稳定可靠的定位方式并写出点击该控件的代码。要求考虑等待控件出现并加入简单的异常处理。”提前准备好这样的模板能极大提高AI生成代码的准确率和可用性。3. AI辅助测试开发的核心工作流解析环境准备好后我们来看整个工作流是如何运转的。它不是一个全自动的魔法而是一个“人机协同”的循环。3.1 元素定位策略的AI优化这是AI辅助最能立竿见影的环节。在weditor中当你点击一个控件右侧会显示其所有属性和可能的定位方式如id、xpath、text等。新手常犯的错误是直接使用weditor生成的绝对xpath这种路径又长又脆弱UI稍改就失效。传统做法我需要自己判断优先用resource-id没有则用text再考虑用className加上其他属性组合。这个过程需要经验。AI辅助做法我将控件的所有属性复制到Cursor的聊天框然后提问“基于这些属性为uiautomator2推荐一个最稳定且高效的定位策略并解释原因。” AI不仅会给出代码例如d(resourceId“com.example.app:id/login_button”).click()还会分析“优先使用resource-id因为它是开发者赋予的唯一标识稳定性最高。如果resource-id为空则使用text但需要注意多语言和文本变更风险。应避免使用bounds因为它在不同分辨率设备上会变化。”更进阶的用法是当面对一个列表中的相似项目时我可以把多个相似项的属性一起给AI让它生成一个能匹配列表中特定项的通用定位器比如使用childSelector或xpath中的索引和文本组合。AI能帮我构思出我可能没想到的、更优雅的定位方式。3.2 从操作描述到脚本片段的自动生成当我们设计一个测试用例时脑子里想的是自然语言“先点击首页的‘我的’选项卡然后检查‘登录/注册’按钮是否存在如果存在就点击接着在用户名输入框输入‘testuser’……”在AI辅助下这个思维过程可以直接转化为生产力。我不需要自己逐个元素去查属性、写定位、编代码。我可以在weditor中依次点击“我的”选项卡、“登录/注册”按钮、用户名输入框把它们的属性信息分别保存下来。在Cursor中这样描述“请帮我编写一个uiautomator2的测试函数顺序执行以下操作 a. 点击属性为resource-id‘com.xxx.app:id/tab_mine’的控件。 b. 等待并检查属性为text‘登录/注册’的控件是否存在存在则点击。 c. 向属性为resource-id‘com.xxx.app:id/username_et’的控件输入文本‘testuser’。 请为每个操作添加适当的显式等待使用d.watcher或time.sleep的替代方案并包含基本的异常处理如图片找不到时的日志记录和失败标记。”AI会根据这个描述生成一个结构清晰、包含等待和异常处理框架的函数。我的工作就从“写代码”变成了“设计用例描述”和“审核优化AI生成的代码”。对于重复性的页面操作如填写表单效率提升是数量级的。3.3 异常处理与等待逻辑的智能补充等待和异常处理是UI自动化的难点也是脚本健壮性的关键。AI可以在这方面提供很好的建议。智能等待我可以问AI“在uiautomator2中除了time.sleep有哪些更好的方式等待一个resource-id为‘xxx’的控件出现请写出代码示例。” AI会列举出d(resourceId‘xxx’).wait.exists(timeout)、auto.wait包、或者设置全局隐式等待d.implicitly_wait()并分析各自的适用场景。异常处理模板我可以让AI为我生成一个通用的操作封装函数。例如“请写一个名为safe_click的函数它接收一个定位器参数尝试点击如果失败则截图保存并记录错误日志到文件。” AI生成的代码通常会包含try...except UiObjectNotFoundError、except Exception as e等多层捕获以及d.screenshot()和logging.error()的调用这比我手动写要全面和规范得多。我可以将这些AI生成的通用函数收集起来形成我自己的测试基础库后续的脚本编写就会越来越快。3.4 测试用例的生成与数据驱动扩展对于业务逻辑相似但测试数据不同的用例AI的数据驱动测试生成能力非常有用。例如我需要测试登录功能有用户名密码正确、用户名错误、密码错误、空输入等多种情况。我可以先手动编写或让AI生成一个正例的测试脚本。然后准备一个CSV文件或JSON列表里面列明不同的测试数据用户名、密码和预期结果登录成功、提示‘用户名错误’等。接着让AI阅读我已有的测试脚本和这个数据文件要求它“请将这个测试脚本改造成数据驱动模式从test_data.json中读取多组数据循环执行并根据‘expected_result’字段断言不同的结果。”AI能够很好地理解这个需求并生成使用pytest的pytest.mark.parametrize装饰器或者循环读取数据文件的代码框架。这确保了测试用例的覆盖度又避免了大量重复代码。4. 实战演练一个完整的登录测试用例构建我们以一个最常见的“App登录”场景来串联上述所有环节看看AI如何一步步辅助我们完成一个健壮的测试用例。4.1 步骤一使用Weditor捕获界面元素首先打开待测App进入登录界面。启动weditor并连接设备在浏览器中实时查看登录界面。我们需要识别以下关键元素用户名输入框密码输入框登录按钮可能的错误提示框用于断言失败情况在weditor中依次点击这些控件。以用户名输入框为例右侧面板会显示类似如下的信息node: resource-id: com.demo.app:id/et_username text: (可能为空或提示文本) class: android.widget.EditText package: com.demo.app ...将每个关键控件的resource-id或备用属性如text记录下来。最好用文本编辑器或便签临时保存。4.2 步骤二与AI协作生成基础脚本打开Cursor在项目中的测试文件如test_login.py里或者直接在Chat界面开始与AI对话。第一轮提示生成页面对象模型雏形“我正在为一个安卓App编写登录功能的UI自动化测试。我计划使用uiautomator2。我发现了以下页面元素请帮我创建一个LoginPage类来封装它们用户名输入框: resource-idcom.demo.app:id/et_username密码输入框: resource-idcom.demo.app:id/et_password登录按钮: resource-idcom.demo.app:id/btn_login错误提示区域: resource-idcom.demo.app:id/tv_error_msg(可能用于显示‘用户名或密码错误’)请为这个类编写定位器和基本操作方法如input_username,input_password,click_login。另外请为‘错误提示信息’编写一个获取文本的方法。”AI会生成一个结构清晰的LoginPage类使用self.d(resourceId...)的方式进行定位并在方法中加入简单的等待逻辑如.wait.exists()。第二轮提示生成测试用例函数“基于上面创建的LoginPage类请帮我编写一个pytest测试函数test_login_success。测试步骤是启动App假设已有一个setup方法连接设备。跳转到登录页这部分先简单用time.sleep或已知Activity跳转稍后优化。使用LoginPage对象输入正确的用户名‘correctUser’和密码‘correctPass’。点击登录按钮。验证登录是否成功。成功的标志可能是当前Activity跳转到MainActivity或者首页出现某个特定元素例如resource-idcom.demo.app:id/tv_welcome。请选择一种稳健的方式进行断言。请包含必要的import并考虑使用pytest的fixture来管理uiautomator2的设备连接(d)。”AI会生成一个包含pytest.fixture和完整测试函数的文件。它可能会使用d.app_current()[activity]来判断Activity跳转或者使用d(resourceId‘welcome_id’).exists()来断言元素存在。4.3 步骤三利用AI增强脚本健壮性基础脚本有了但很脆弱。我们开始让AI帮忙加固。第三轮提示优化等待与异常处理“上面生成的测试脚本在‘跳转到登录页’和‘等待登录成功元素’时使用了time.sleep这不够健壮。请帮我优化将‘跳转到登录页’的等待改为使用d.watcher(‘LOGIN_PAGE’).when(resourceId‘et_username’).click()这种监听器模式或者使用显式等待d(resourceId‘et_username’).wait.exists(timeout10)。在LoginPage的click_login方法里加入异常处理。如果点击后一段时间内比如5秒既没有跳转到成功页面也没有出现错误提示则认为超时失败并自动截图保存。在测试函数test_login_success的最后无论成功与否都请添加一个清理步骤比如按返回键退出到首页为下一个测试做准备。”AI会根据要求将time.sleep替换为更智能的等待策略并在关键操作外添加try...except块在异常时调用d.screenshot()并输出日志。它还可能引入pytest的yield fixture来实现测试后的清理。第四轮提示实现数据驱动测试“现在我需要测试登录失败的情况。请帮我扩展测试使用数据驱动的方式测试以下三组数据usernamepasswordexpected_resultwrongUsercorrectPass‘用户名或密码错误’correctUserwrongPass‘用户名或密码错误’(空)(空)‘请输入用户名’ (或类似提示)预期结果expected_result是错误提示框(tv_error_msg)中应该出现的文本片段。 请使用pytest的参数化功能来实现并将成功的用例和失败的用例分开在不同的测试函数或类中以保持清晰。”AI会生成一个新的测试函数例如test_login_failure并使用pytest.mark.parametrize装饰器。它会读取我们提供的参数列表在测试中执行操作并使用assert expected_result in error_text的方式进行断言。4.4 步骤四运行调试与AI辅助排错运行生成的测试脚本很可能会遇到失败。这时AI又成了排错助手。将错误的堆栈信息复制给AI并描述上下文“我在运行这个登录测试时在输入用户名这一步失败了报错UiObjectNotFoundError: Could not find UI object with selector。我确认设备已连接并且weditor里能看到这个resource-id。可能的原因是什么如何修改”AI可能会分析出几种可能应用包名或Activity不对启动的不是被测App。检查d.app_start(“com.demo.app”)。页面未加载完成需要更长的等待或更准确的等待条件。建议在输入前增加d(resourceId‘et_username’).wait.exists(timeout15)。resource-id动态变化某些App的resource-id可能包含时间戳或随机数。建议使用其他属性组合定位或者使用xpath的部分匹配(contains)。根据AI的建议我们返回weditor再次确认元素属性并修改脚本中的定位策略或等待逻辑。这个过程可能需要几次迭代但每次AI都能提供专业的排查方向比自己盲目搜索快得多。5. 进阶技巧AI在测试框架维护与优化中的应用当测试脚本越来越多我们就进入了框架维护阶段。AI在这里也能发挥巨大作用。5.1 测试代码的重构与模式优化随着PageObject类增多你可能会发现代码有重复。例如每个页面类都有类似的初始化方法、都有对d的引用。你可以让AI帮忙重构。提示“我目前有LoginPage、HomePage、SettingsPage等多个页面类它们都接收一个uiautomator2的d对象作为初始化参数。请帮我设计一个BasePage基类将公共的属性和方法比如一个通用的wait_for_element方法抽离进去。然后重写现有的页面类使其继承自BasePage。”AI会帮你创建这个基类并修改子类使代码结构更清晰符合设计模式。5.2 生成测试报告与日志增强原始的pytest输出不够直观。我们可以让AI帮忙集成更漂亮的报告比如pytest-html或allure。提示“在我的UI自动化测试项目中我想生成HTML格式的测试报告。请帮我修改pytest的配置集成pytest-html插件。要求报告包含测试用例名称、状态、耗时并且在测试失败时自动将uiautomator2截取的屏幕图片嵌入到报告中。请给出具体的conftest.py配置和钩子函数写法。”AI会提供详细的配置代码告诉你如何安装插件如何在pytest_runtest_makereport钩子中捕获测试失败时的异常并调用d.screenshot()将图片以附件形式添加到报告中。5.3 探索性测试与异常场景启发AI甚至可以帮助我们设计测试用例。我们可以向AI描述一个业务场景让它思考可能出错的点。提示“我正在测试一个电商App的购物车功能。用户可以将商品加入购物车修改数量然后结算。你能从UI交互、网络异常、数据边界等角度列出10个可能需要进行自动化测试的异常或边界场景吗”AI可能会给出网络中断时点击结算、购物车商品数量输入为0或负数、库存不足时结算、重复添加同一商品、在结算页面快速来回点击按钮等等。这些场景可以作为我们编写新测试用例的灵感来源补充我们思维的盲区。6. 常见问题、局限性与应对策略实录在实际融合AI与weditor进行自动化测试开发的过程中我踩过不少坑也总结出一些经验和当前技术的局限性。6.1 AI生成代码的准确性与可靠性问题问题AI生成的代码并非100%正确或最优。它可能使用已弃用的API或者给出的定位策略在实际环境中不稳定例如过度依赖text属性而该属性容易随版本变化。应对策略永远保持审查将AI视为一个强大的初级或中级助手而非替代品。你必须理解并审查它生成的每一行代码。特别是涉及等待逻辑、异常处理和资源清理的部分。提供更精确的上下文在提示词中明确指出你使用的库和版本如uiautomator22.16.0以及项目的编码规范。这能提高生成代码的适用性。迭代优化不要期望一次提示就能得到完美代码。采用“生成-运行-审查-反馈修正”的循环。把运行报错信息反馈给AI让它自我修正。建立代码片段库将AI生成的、经过你验证的可靠代码片段如稳定的等待函数、页面基类保存下来形成团队内部的“最佳实践库”。后续可以要求AI参考这些库的代码风格和模式进行生成。6.2 动态元素与不稳定UI的挑战问题很多现代App使用动态ID、列表无限滚动、或复杂的自定义控件weditor抓取到的属性可能每次都不一样或者AI难以根据静态信息生成稳定的操作逻辑。应对策略结合多种定位策略指导AI使用组合定位例如d(className“android.widget.TextView”, text“确定”)或者使用相对定位和父子关系。利用AI理解上下文将整个页面结构或相邻控件的属性一起提供给AI让它分析出更通用的规律。例如“这是一个商品列表每个商品项都有一个‘加入购物车’按钮但它们的resource-id都包含相同的后缀请生成一个能匹配所有此类按钮的XPath表达式。”引入图像识别辅助对于难以用属性定位的图标或验证码可以将weditor的截图功能与OCR或图像模板匹配如airtest的Template结合。你可以让AI帮你编写调用这些图像识别库的代码片段作为属性定位的补充。6.3 提示工程Prompt Engineering的心得与AI协作的效率很大程度上取决于你“提问”的水平。角色设定在提示词开头为AI设定角色效果显著。例如“你是一个经验丰富的测试开发工程师精通uiautomator2和pytest。”结构化输入对于复杂任务分步骤提出要求。先让AI设计类结构再让它填充方法最后让它编写测试用例。比一次性提出所有要求效果更好。提供反面示例如果你知道某种做法不好直接告诉AI。“请不要使用time.sleep进行固定等待请使用显式等待。” “避免使用绝对XPath。”要求解释在让AI生成代码后可以追加一句“请解释一下这段代码中等待逻辑是如何工作的以及为什么这样写更健壮。” 这不仅能帮助你学习也能让AI“反思”其输出有时它会发现并修正自己逻辑上的小漏洞。6.4 工作流整合与团队协作考量问题个人使用很顺畅但如何融入团队现有的CI/CD流程如何保证AI生成的代码风格一致应对策略制定团队规范团队需要约定使用AI辅助的“红线”。例如所有AI生成的代码必须经过至少一位同事的人工审查才能合并必须遵循项目的代码格式化工具如black、isort。创建共享提示词库团队可以共同维护一个针对常用场景如“创建PageObject类”、“生成数据驱动测试”的标准化提示词模板。这能保证输出代码风格和结构的一致性。关注可维护性AI擅长生成代码但不擅长长期维护。团队必须确保测试框架的核心架构、基础工具类是清晰和稳定的。AI应主要用于在既定框架下填充具体内容而不是随意更改架构。7. 未来展望AI Agent与自动化测试的深度融合目前我们探讨的主要还是“辅助生成”模式即人类主导AI协助。但未来的方向很可能是向“AI Agent”演进。想象一下你给AI Agent一个任务“测试一下App的登录功能包括成功和失败场景。” Agent可以自动启动模拟器或真机安装App。打开weditor或类似工具探索界面识别出登录相关的控件。自主设计测试用例包括正常和边界值。编写、执行测试脚本并生成测试报告。如果遇到错误如元素找不到能自动分析原因是定位器问题还是页面未加载并尝试调整策略换一种定位方式或增加等待。这听起来还很遥远但当前一些AI编码工具已经展现出一定的自主规划和执行能力。对于我们测试开发者来说这意味着未来的核心价值可能不再是编写大量的find_element和click而是设计测试策略、定义验收标准、构建和维护能让AI Agent高效工作的测试基础设施与环境。我们现在用AI辅助weditor做自动化正是在为那个未来积累经验和准备技能栈。从手动录制回放到脚本编写再到AI辅助生成最终走向智能体自主测试效率的提升是革命性的。而我们现在要做的就是拥抱这个变化先人一步把AI变成我们手中最趁手的利器。