微信扫码
添加专属顾问
 
                        我要投稿
AI助力UI自动化测试脚本自愈,智能解决元素定位失效等四大难题,显著提升脚本稳定性。 核心内容: 1. UI自动化测试脚本失败的四大主要原因分析 2. 基于Deepseek API的AI自愈方案设计与实现 3. 具体配置和脚本调整的实践指南
 
                                当前UI自动化测试脚本的稳定性受多种因素影响,导致执行失败率较高,主要失败原因包括:
1.元素定位失效:前端属性(ID/Class/XPath)动态变更,导致脚本无法识别元素
2.页面结构重构:DOM层级或组件库升级引发原有定位策略失效
3.环境问题:网络延迟、浏览器版本差异等造成执行中断
4.业务逻辑变更:需求调整导致流程变化,原有用例不再适用
所以引入AI辅助的自愈机制,希望通过 AI 实现智能定位修复,通过AI 识别页面结构变化,自动生成备选选择器,自动调整定位策略,以适应前端变更,从而减少人工干预,降低维护成本降低,提高脚本稳定性。
根据UI自动化执行失败的原因,制定不同的修复策略,具体如下
本文主要分享通过调用AI api 根据错误原因,推荐心得元素定位器列表,逐一验证新的元素定位器,验证通过则修改脚本。
调用方式:
import requests API_KEY = "your_api_key" url = "https://api.deepseek.com/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": "deepseek-chat", "messages": [ {"role": "user", "content": "请解释Transformer的注意力机制"} ], "temperature": 0.7, "max_tokens": 1000 } response = requests.post(url, json=payload, headers=headers) print(response.json())Deepseek API 返回数据类型:支持json数据返回
AI_API_KEY = Bearer sk-keyxxxx #需要申请API_URL = https://api.deepseek.com/v1/chat/completions
2. 自愈脚本 self_healing_locator.py
1. 构建promot模版
2. 调用AI API输出推荐选择器列表
3. 遍历校验候选选择器有效性,验证通过则修改脚本;
import reimport requestsfrom playwright.sync_api import Pagefrom common.rwConfig import rwConfigfrom common.log import logger# 获取配置文件信息AI_API_KEY = rwConfig().getConfigOption(option='AI_API_KEY', section="common")API_URL = rwConfig().getConfigOption(option='API_URL', section="common")class Healer:def __init__(self, page: Page):self.page = pagedef deepseek(self, prompt: str) -> list:"""调用AI API 生成定位器"""headers = {"Authorization": AI_API_KEY,"Content-Type": "application/json"}# 调用deepseek APIpayload = {"model": "deepseek-chat","messages": [{"role": "user", "content": prompt}],"temperature": 0.7,"max_tokens": 1000}try:response = requests.post(API_URL, headers=headers, json=payload)logger.info(f"API调用成功: {response.json()['choices'][0]['message']['content']}")selector_list = eval(response.json()['choices'][0]['message']['content'])logger.info(f"AI推荐定位器列表: {selector_list}")# 返回推荐列表return selector_listexcept Exception as e:logger.info(f"API调用失败: {str(e)}")return []def locator_prompt(self, pass_selector:str,failed_selector:str) ->str:"""构建元素定位提示词模板"""# 获取正确元素区域的页面内容dom_snippet =self.get_html_around_element(pass_selector)# logger.info(f"截断dom内容: {dom_snippet}")return f"""请为Playwright测试生成3个可靠的元素定位器,要求:1. 代替定位失败的选择器:{failed_selector}2. 基于当前页面片段(可能被截断):{dom_snippet}输出content要求:- 按稳定性优先级排序,剔除需要开发人员参与的定位方式- 使用CSS或XPath格式- 输出为Python列表格式,如:["1", "2"],剔除其他文案,仅保留list内容"""def heal_element(self,pass_selector:str,failed_selector:str, test_file:str) ->bool:"""执行自愈流程"""i = 0prompt =self.locator_prompt(pass_selector,failed_selector)logger.info(f"生成定位器提示词: {prompt}")# 调用AI API 生成定位器elements =self.deepseek(prompt)# 验证选择器有效性for selector in elements:logger.info(f"第【{i+1}】次验证选择器有效性: {selector}")if self._try_selector(selector):# 更新测试脚本文件logger.info(f"更新测试脚本文件: {test_file} 失败元素: {failed_selector} 新定位器: {selector}")self.update_file(test_file, failed_selector, selector)return Trueelse:i += 1if i > 3:logger.info(f"AI推荐的选择器均 验证失败")return Falselogger.info(f"未找到有效定位器: {failed_selector}")return Falsedef get_html(self, selector, chars_before=2000, chars_after=10000):# 获失败元素局部页面的HTMLfull_html = self.page.content()# 获取元素的outerHTML和位置element_html = self.page.locator(selector).evaluate('el => el.outerHTML')element_index = full_html.find(element_html)if element_index == -1:logger.info("关键元素 未找到")return None# 计算截取范围start = max(0, element_index - chars_before)end = min(len(full_html), element_index + len(element_html) + chars_after)# 截取页面片段surrounding_html = full_html[start:end]return surrounding_htmldef try_selector(self, selector: str) -> bool:"""验证选择器有效性"""try:self.page.wait_for_selector(selector, timeout=3000)logger.info(f"选择器 有效: {selector}")return Trueexcept:logger.info(f"选择器 无效: {selector}")return Falsedef update_file(self, file_path: str, old: str, new: str):"""更新测试脚本文件"""with open(file_path, "r") as f:content = f.read()updated = re.sub(rf'([\'"])({re.escape(old)})([\'"])',lambda m: f"{m.group(1)}{new}{m.group(3)}",content)logger.info(f"更新后的内容: {updated}")with open(file_path, "w") as f:f.write(updated)
3. 测试demo
import pytestfrom playwright.sync_api import Page, expectfrom common.self_healing_locator import SaucedemoHealerfrom common.rwConfig import rwConfigfrom conftest import *URL = "https://xxxxxx/sso"headless=bool(int(rwConfig().getConfigOption(option='headless')))def page():with sync_playwright() as playwright:browser = playwright.chromium.launch(headless=headless)#保存登录信息# context = browser.new_context(storage_state="./data/state.json")context = browser.new_context(page=context.new_page()page.goto(URL)yield pagebrowser.close()def healer(page):yield Healer(page)def test_checkout_flow(page, healer: Healer):try:page.goto(URL)visible = page.get_by_role("heading", name="手机密码登录").is_visible()if not visible:# 切换到手机号密码登录页面time.sleep(1)page.locator("xxwc-togger-sign div").nth(1).click()# 输入手机号page.locator("#phone").fill("xxxxxx")# 输入密码page.locator("#pwd").fill("xxxxxx")# 点击登录按钮page.locator(".xxx-button-login").click()except Exception as e:if "#pwd" in str(e):# 触发自愈流程:传入正确元素、失败元素if healer.heal_element("#phone","#pwd", __file__):pytest.fail("元素定位已自动修复,请重新运行测试")else:pytest.fail("元素定位修复失败 END")raise e
当前阶段遗留问题:
1. 部分页面的html内容获取失败,导致推荐选择器获取失败
2.自愈脚本如何快速运用到全局case中
3. 在 pytest中,使用的是 --reruns或其他重试机制(如 pytest-rerunfailures),所以重试时不会自动加载修改后的脚本,因为:
Python 在首次导入模块时会将其编译为字节码(.pyc),并缓存在 __pycache__目录中。
重试时,pytest仍会使用内存中已加载的模块(即第一次执行时的脚本版本),不会重新读取磁盘上的修改
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2025-10-31
Opera One升级内置AI 迎来智能助手新纪元
2025-10-31
LangExtract——大模型文本提炼工具
2025-10-31
用户测评|DeepSeek-OCR,你用了吗?
2025-10-31
从Palantir智能化技术路线看AI时代企业级架构平台的核心战略位置
2025-10-31
OpenAI 公开 Atlas 架构:为 Agent 重新发明浏览器
2025-10-31
Palantir 本体论模式:重塑企业 AI 应用的 “语义根基” 与产业启示
2025-10-31
树莓派这种“玩具级”设备,真能跑大模型吗?
2025-10-30
Cursor 2.0的一些有趣的新特性
 
            2025-08-21
2025-08-21
2025-08-19
2025-09-16
2025-10-02
2025-09-08
2025-09-17
2025-08-19
2025-09-29
2025-08-20