前言

大家好,上一期我们用 LangChain Agent + Playwright + POM 实现了自然语言驱动测试。本期继续进阶,重点解决 Web UI 自动化最头疼的两个问题:

  1. 页面元素变化导致脚本失效(传统痛点)
  2. UI 样式/布局变更后的回归验证

通过 Self-Healing(自愈)机制 + AI 视觉回归测试,让脚本具备一定的“智能适应能力”。

一、Self-Healing 自愈测试核心原理

当传统定位器失效时,Agent 会:

  • 重新加载当前页面 DOM
  • 使用 AI 分析页面结构,寻找语义相似的替代元素
  • 自动更新定位器并重试

二、环境准备(新增依赖)

Bash

pip install langchain-ollama pillow opencv-python numpy
# 视觉模型推荐使用本地 llava 或 moondream(Ollama 支持)
ollama pull llava:13b

三、完整代码实战

1. 增强 BasePage(增加自愈能力)

Python

from playwright.sync_api import Page, expect
import time
from langchain_ollama import ChatOllama

class BasePage:
    def __init__(self, page: Page):
        self.page = page
        self.llm = ChatOllama(model="llava:13b", temperature=0.1)  # 视觉模型
    
    def self_healing_click(self, original_selector: str, description: str, max_retries=2):
        """自愈点击:失败后自动寻找替代元素"""
        for attempt in range(max_retries + 1):
            try:
                self.page.wait_for_selector(original_selector, timeout=8000)
                self.page.locator(original_selector).click()
                print(f"✅ 使用原始定位器成功: {original_selector}")
                return True
            except Exception as e:
                print(f"第 {attempt+1} 次尝试失败: {str(e)}")
                if attempt == max_retries:
                    break
                # 触发自愈
                alternative = self._find_alternative_locator(description)
                if alternative:
                    print(f"🔄 自愈成功,使用新定位器: {alternative}")
                    self.page.locator(alternative).click()
                    return True
                time.sleep(1)
        self.take_screenshot("self_healing_failed")
        return False

    def _find_alternative_locator(self, element_description: str):
        """调用视觉 + DOM 分析寻找替代定位器"""
        html = self.page.content()[:15000]  # 截取部分 DOM
        prompt = f"""页面当前HTML结构:{html[:8000]}
        目标元素描述:{element_description}
        请返回一个稳定的 Playwright 定位器(优先使用 getByRole 或 getByText),只返回代码片段,不要解释。"""
        
        response = self.llm.invoke(prompt)
        return response.content.strip()

2. 视觉回归测试工具

Python

import cv2
from PIL import Image
import numpy as np

@tool
def visual_regression_check(baseline_img: str, current_screenshot: str, threshold=0.95):
    """视觉回归比对"""
    try:
        img1 = cv2.imread(baseline_img)
        img2 = cv2.imread(current_screenshot)
        img1 = cv2.resize(img1, (img2.shape[1], img2.shape[0]))
        
        diff = cv2.absdiff(img1, img2)
        similarity = 1 - (np.sum(diff) / (img1.size * 255))
        
        if similarity >= threshold:
            return f"✅ 视觉回归通过,相似度: {similarity:.4f}"
        else:
            return f"❌ 视觉差异过大,相似度: {similarity:.4f}(阈值 {threshold})"
    except Exception as e:
        return f"视觉比对异常: {str(e)}"

3. Agent 集成(Self-Healing + 视觉)

Python

prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一位高级 AI 测试工程师。
    具备 Self-Healing 能力:当定位器失效时,使用元素描述重新查找。
    支持视觉回归测试。
    所有代码必须基于 POM 模式,并包含详细错误处理和截图。"""),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}")
])

tools = [execute_playwright_test, visual_regression_check]
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

使用示例

Python

run_ai_test("登录电商网站后,点击'我的订单'按钮(描述:右上角用户菜单中的订单入口),然后进行视觉回归检查")

四、生产落地效果评估

Self-Healing 效果

  • 简单元素变化:自愈成功率 ≈ 75%-85%
  • 复杂页面:需结合人工规则 + AI 混合使用

视觉回归优势

  • 能捕捉到文字大小、颜色、布局等肉眼容易忽略的变化
  • 结合 AI 描述差异(后续可升级)

生产建议

  1. 建立 Baseline 截图库(Git 管理)
  2. 重要页面强制视觉回归检查
  3. 自愈日志记录到 Allure 报告,便于 Review
  4. 敏感页面仍需人工固定定位器兜底

踩坑总结

  • 视觉模型对复杂页面理解有限,建议混合使用 DOM + 视觉
  • 自愈不能完全替代人工 Review,要做双保险
  • 性能:复杂自愈会增加执行时间,建议只对核心流程开启

五、今日感悟

加入 Self-Healing 和视觉回归后,脚本的鲁棒性有了质的飞跃。这让我更加坚信:未来的自动化测试一定是 AI + 传统框架 + 人工智慧 的混合模式。

下一期预告(AI Web UI 自动化专栏 #03)多 Agent 协作测试平台实战(Planner + Coder + Executor + Reviewer 四个 Agent 分工)


Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐