一、背景
- 背景:
- 组件库全局改动场景多,组件之间耦合场景多–时常需要全场景回归
- 组件库demo有200多个,手动全局回归耗时耗力
- 细微偏差纯视觉无法辨别
- 可行性分析:
- 组件库功能占比
- L1(视觉层):图片对比确保整体视觉一致性(占比40%)
- L2(属性层):传统断言验证核心功能(占比50%)
- L3(交互层):行为模拟验证动态逻辑(占比10%)
- 时间成本分析
- 视觉层:5个工作日可实现所有demo截图对比,无需补充场景,单月用例维护时间只需2个工作日
- 属性层:无法一步实现所有demo属性测试,单月用例维护/场景维护或大于5个工作日
- 技术实现可行性
- 视觉层:python 可实现,selenium可实现浏览器驱动和页面截图,PIL可实现图片对比
- 属性层:可实现架构多,但目前没有找到快速获取组件属性的方式和属性校准的方式
- 组件库功能占比
- 应用场景:
- 视觉密集型组件(图表/静态图等)
- 回归测试中视觉回归防御
- 整体思路:
- 找到组件库demo对应URL规则批量抓取
- 截图保存到本地
- PIL工具对比输出差异
二、操作步骤
2.1 开发前的准备工作
准备工作一
- Selenium驱动安装
准备工作二 - demo目录结构分析
2.2 开发
代码逻辑:
爬取所有路径下demo名称,数组形式输出
import osdef list_directories(path):"""列出指定路径下的所有直接子目录返回格式:目录名称列表(按字母顺序排序)"""try:# 获取路径下所有条目entries = os.listdir(path)# 过滤出目录并排序directories = sorted([entry for entry in entriesif os.path.isdir(os.path.join(path, entry))])return directoriesexcept FileNotFoundError:print(f"错误:路径不存在 - {path}")return []except PermissionError:print(f"错误:没有访问权限 - {path}")return []except Exception as e:print(f"未知错误:{str(e)}")return []if __name__ == "__main__":drislist = []target_path = "/Users/forest/Desktop/"dirs = list_directories(target_path)if dirs:print(f"在 {target_path} 下找到 {len(dirs)} 个目录:")for idx, directory in enumerate(dirs, 1):print(f"{idx}. {directory}")target_path1 = "/Users/forest/Desktop/"+directory+"/demo"dirs1 = list_directories(target_path1)if dirs1:for idx, directory1 in enumerate(dirs1, 1):print(f"{idx}. {directory1}")drislist.append(directory+"-"+directory1)else:print("未找到任何目录或路径无效")# 测试用例print(drislist)test_path = "/Users/forest/Desktop/"
图片对比compare_images方法
from PIL import Image, ImageChops
from datetime import datetimedef compare_images(image1_path, image2_path, output_diff_path=None):# 打开两张图片img1 = Image.open(image1_path)img2 = Image.open(image2_path)# 确保图片尺寸相同if img1.size != img2.size:raise ValueError("图片尺寸不一致,无法对比!")# 计算差异diff = ImageChops.difference(img1, img2)if diff.getbbox() is None:print("图片完全一致!")return 0.0 # 差异百分比# 统计差异像素pixels = list(diff.getdata())diff_pixels = sum(1 for pixel in pixels if pixel != (0, 0, 0, 0))total_pixels = len(pixels)diff_percentage = (diff_pixels / total_pixels) * 100# 保存差异图(可选)if output_diff_path:diff.save(output_diff_path)print(f"差异图已保存至: {output_diff_path}")print(f"图片差异百分比: {diff_percentage:.2f}%")return diff_percentage
主方法
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from datetime import datetimefrom app.diff.diff import compare_images
from app.diff.moduleDemoData import moduleDemoDatasindex = 0now = datetime.now()
date_str1 = now.strftime("%Y-%m-%d")
date_str ='2025-08-11'
print(date_str)
# 配置 Chrome 选项(无头模式)
chrome_options = Options()
chrome_options.add_argument("--headless") # 无界面模式
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920,1080") # 截图尺寸# 启动浏览器driver = webdriver.Chrome(options=chrome_options)output_diff_path = '/Users/forest/PycharmProjects/static'# 等待页面加载(可根据需要调整)
passModuleDemoData = []
localModuleDemoData = []
for moduleDemoData in moduleDemoDatas:passUrl = "http://localhost:4600/v2/~examplesh-"+moduleDemoData+"-example"driver.get(passUrl)time.sleep(5)
# 截图并保存passScreenshot_path = "/Users/forest/pass"+moduleDemoData+".png"driver.save_screenshot(passScreenshot_path)print(f"截图已保存至: {passScreenshot_path}")passModuleDemoData.append(passScreenshot_path)for moduleDemoData in moduleDemoDatas:localUrl = "-"+moduleDemoData+"-example"driver.get(localUrl)time.sleep(5)# 截图并保存localScreenshot_path = "moduleDemoData+".png"driver.save_screenshot(localScreenshot_path)print(f"截图已保存至: {localScreenshot_path}")localModuleDemoData.append(localScreenshot_path)for moduleDemoData in moduleDemoDatas:print(compare_images(passModuleDemoData[index], localModuleDemoData[index]))if compare_images(passModuleDemoData[index], localModuleDemoData[index]) > 0:compare_images(passModuleDemoData[index], localModuleDemoData[index], output_diff_path+"error"+date_str1+moduleDemoData+".png")print("error"+moduleDemoData)index += 1
# 关闭浏览器
driver.quit()
参数列表:罗列代码中涉及的参数和含义
参数 含义
compare_images :return 0无差异
暂时无法在飞书文档外展示此内容
三、总结
总结本次技术应用中可积累的代码和经验
技术经验
有待提升
- 可分批运行
- …版本发现bug数
- 样式隔离节省回归时间30%以上
- 滚动截图
- …