恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SeleniumBase 视觉回归测试实战:用 check_window() 捕获网页布局变更(以 xkcd logo 尺寸变化为例)
首页
资讯中心
/
SeleniumBase 视觉回归测试实战:用 check_window() 捕获网页布局变更(以 xkcd logo 尺寸变化为例)
SeleniumBase 视觉回归测试实战:用 check_window() 捕获网页布局变更(以 xkcd logo 尺寸变化为例)
发布时间:2026/9/15 18:36:19
SeleniumBase 视觉回归测试实战用 check_window() 捕获网页布局变更以 xkcd logo 尺寸变化为例【免费下载链接】SeleniumBaseAPIs for browser automation, testing, and bypassing bot-detection. Includes CDP Mode: A stealthy configuration for chromium that passes every bot detection test.项目地址: https://gitcode.com/GitHub_Trending/se/SeleniumBase本文以 SeleniumBase 仓库中examples/visual_testing/case_plans/test_layout_fail.VisualLayoutFailureTests.test_xkcd_logo_change.md用例计划文档为骨架完整还原基线建立 → 篡改页面 → 触发差异 → 测试失败的视觉回归测试全流程并结合 test_layout_fail.py、check_window() 源码 与 visual_testing/ReadMe.md 深入讲解check_window()的 level 分级机制、set_attribute()的实现原理、side_by_side.html对比报告以及--visual_baseline命令行参数。读完本文你将能独立编写基于 HTML 标签比对的视觉回归用例并读懂失败时的差异输出与日志产物。一、用例计划文档解读一场注定失败且故意为之的测试关联文档examples/visual_testing/case_plans/test_layout_fail.VisualLayoutFailureTests.test_xkcd_logo_change.md以表格形式给出了该用例的计划| # | Step Description | Expected Result | | - | ---------------- | --------------- | | 1 | Open https://xkcd.com/554/.Callcheck_window()withbaselineTrue. | | | 2 | Resize the logo usingset_attribute().Callcheck_window()withlevel3. | The test fails because the logo has changed.Aside_by_side.htmlfile appears in the specificlatest_logs/folder of the test. |这份计划传达了两个关键信息测试意图用例名为test_xkcd_logo_change属于VisualLayoutFailureTests测试类继承自BaseCase。它并不是在验证页面没变化而是在主动制造页面变化并验证框架能够检测出来——这是一种典型的负向测试negative test用于证明视觉回归检测机制本身有效。预期结果在 logo 被改尺寸后check_window(level3)必须抛异常导致测试失败同时在测试对应的latest_logs/目录下生成side_by_side.html对比报告文件。文档虽短但它是整个视觉测试功能的一个验收标准只有检测到差异、测试失败、并产出对比报告这套机制才算正常工作。二、配套源码test_layout_fail.py 的完整实现用例计划的落地方案在 examples/visual_testing/test_layout_fail.py 中核心代码如下from seleniumbase import BaseCase BaseCase.main(__name__, __file__) class VisualLayoutFailureTests(BaseCase): def test_xkcd_logo_change(self): self.goto(https://xkcd.com/554/) print(\nCreating baseline in visual_baseline folder.) self.check_window(namexkcd_554, baselineTrue) # Change height: (83 - 110) , Change width: (185 - 120) self.set_attribute([altxkcd.com logo], height, 110) self.set_attribute([altxkcd.com logo], width, 120) print((This test should fail)) # due to a resized logo self.check_window(namexkcd_554, level3)执行流程分四步self.goto(https://xkcd.com/554/)打开目标页面xkcd 第 554 期漫画页页首带站点 logoself.check_window(namexkcd_554, baselineTrue)建立视觉基线以当前页面为基准快照self.set_attribute(...)通过 JavaScript 把 logo 元素的height从 83 改为 110、width从 185 改为 120人为破坏布局self.check_window(namexkcd_554, level3)以最严格的 level3 级别与基线比对必然触发差异、抛出异常。注意BaseCase.main(__name__, __file__)让脚本既可被 pytest 收集也可直接python test_layout_fail.py运行。仓库中同目录的 layout_test.py 是同一机制的变体使用不同 level 依次比对、并用assert_raises显式断言异常可作为进阶参考。三、check_window() 源码级解析基线如何建立、level 如何分级check_window()定义于 seleniumbase/fixtures/base_case.py完整签名如下def check_window( self, namedefault, level0, baselineFalse, check_domainTrue, full_diffFalse, ):3.1 基线建立机制第一次对某个唯一的name调用check_window()时会在visual_baseline/目录下按测试名/name参数建立基线文件夹其中包含来自源码 docstring 与 visual_testing/ReadMe.mdpage_url.txt—— 当前窗口的 URLbaseline.png—— 基线截图tags_level1.txt—— 页面 HTML 标签列表tags_level2.txt—— HTML 标签 属性名tags_level3.txt—— HTML 标签 属性名和属性值。后续调用会把最新窗口的 HTML 标签结构与基线中保存的文本逐项比较同时保存一张latest.png方便人工判断是否需要重置基线。视觉回归的核心不是像素对比而是 HTML 标签树对比——这是 SeleniumBase 视觉测试与一般截图像素比对方案的本质区别ReadMe 明确说明Instead of comparing pixels from screenshots, layout differences can be detected by comparing HTML tags and attributes。3.2 level 分级体系源码 docstring 对 level 的解释level0DRY RUN试运行——执行与基线比较并打印差异但即使发现差异也不会让测试失败level1只比较 HTML 标签对照tags_level1.txtlevel2比较标签 属性名对照tags_level1.txt与tags_level2.txtlevel3比较标签 属性名 属性值对照全部三个 tags 文件最严格。level 只影响后续比较时的严格度首次建立基线或--visual_baseline重置基线时 level 不生效。此外源码还会校验 level 必须为 0/1/2/3否则抛出Parameter level must be set to 0, 1, 2, or 3!。当check_domainTrue默认时若当前 URL 域名与基线记录不一致会直接报Page Domain Mismatch Failure。3.3 为什么本用例用 level3用例第 2 步选择level3是因为set_attribute()修改的是 logo 的height/width属性值。属性值级别的差异只有 level3或打印模式的 level0才能捕获level1 只看标签名img还是img检测不到level2 只看属性名height、width属性仍在也检测不到level3 才比较属性值83→110、185→120 的差异在此暴露。因此本用例是理解level 严格度如何影响检测能力的最佳教材。对比 case_plans 目录 下的另一份计划python_home_test.VisualLayoutTests.test_python_home_layout_change.md它用level0只打印不失败可以直观体会两种模式的区别。四、set_attribute() 源码级解析如何篡改页面元素set_attribute()定义于 seleniumbase/fixtures/base_case.py签名def set_attribute( self, selector, attribute, value, bycss selector, timeoutNone, scrollFalse, ):其 docstring 说明该方法使用 JavaScript 设置/更新属性只作用于 querySelector() 匹配到的第一个元素。核心实现是拼接并执行一段 JSscript ( document.querySelector(%s).setAttribute(%s,%s); % (css_selector, attribute, value) ) self.execute_script(script)在用例中self.set_attribute([altxkcd.com logo], height, 110) self.set_attribute([altxkcd.com logo], width, 120)即以[altxkcd.com logo]定位 xkcd 站点头部的 logo 图片把height设为 110、width设为 120。注意源码会先用re.escape()与__escape_quotes_if_needed()对选择器、属性名、属性值做转义处理再执行execute_script()因此含引号的属性选择器也能安全传入。同类方法还有set_attributes()作用于querySelectorAll()匹配到的所有元素与set_attribute_all()base_case.py#L2059-L2096可按需扩展使用。set_attribute()属于模拟页面渲染前/渲染后被 JS 改动的手段非常适合用来构造视觉差异场景。五、失败产物side_by_side.html 与 latest_logs 目录用例计划中明确写到预期结果Aside_by_side.htmlfile appears in the specificlatest_logs/folder of the test. 即测试失败后会在该测试对应的latest_logs/目录下生成名为side_by_side.html的对比报告。从 seleniumbase/core/visual_helper.py 的源码结构看该模块提供了get_sbs_html()、get_sbs_table_html()、get_sbs_table_row()、get_sbs_header()、get_sbs_footer()等系列函数visual_helper.py#L23-L96专门用于生成side-by-side并排对比HTML 报告——将baseline.png与latest.png或差异图并排展示方便人眼快速定位布局差异位置。因此一次失败的视觉测试会留下两类产物结构化差异输出控制台打印的AssertionError会指出第一个不匹配的元素及其属性差异。参考 visual_testing/ReadMe.md 中同主题用例resized logo的输出示例大致为AssertionError: First differing element 22: [img[30 chars][height, 83], [src, /s/0b7742.png], [width, 185]]] [img[30 chars][height, 130], [src, /s/0b7742.png], [width, 120]]] ... *** Exception: Level 3 Visual Diff Failure: * HTML tag attribute values dont match the baseline!可视化对比报告latest_logs/下的side_by_side.html把基线截图与最新截图并排渲染visual_helper中get_sbs_html等函数负责拼装 HTML 结构配合latest.png一起辅助判断差异是预期变更还是回归缺陷。full_diff参数值得一提默认False时错误输出只包含列表中第一个不同的元素设为True则输出完整差异列表适合定位多个同时变化的元素。六、如何运行本用例与查看报告在 examples/visual_testing/ 目录下执行pytest test_layout_fail.py --htmlreport.html首次运行会建立基线visual_baseline/目录生成xkcd_554基线文件夹并打印Creating baseline in visual_baseline folder.同一用例再次运行才会真正执行比对逻辑并触发预期失败--htmlreport.html生成 pytest HTML 报告失败详情含side_by_side.html的入口与异常信息会汇总在其中。若页面发生预期内的布局改版导致旧基线不再适用可在命令行追加参数重置基线pytest test_layout_fail.py --visual_baseline只要带上--visual_baselinecheck_window()只重建基线、不做比较因此永远不会失败——这是处理站点主动改版的标准操作源码 docstring 明确说明。七、同目录相关资源想要进一步吃透视觉回归功能可以在仓库中对照阅读test_layout_fail.py —— 本文主角带失败预期的完整用例xkcd_visual_test.py —— 同主题但改用level0打印差异、不失败的变体python_home_test.py —— 通过remove_element()移除按钮制造差异的另一个示例layout_test.py —— 逐级 level 比对 assert_raises显式断言异常的进阶示例case_plans 目录 —— 全部视觉测试的用例计划文档Markdown 表格形式visual_testing/ReadMe.md —— 视觉回归测试的完整说明与多组失败输出样例visual_helper.py ——side_by_side.html报告生成的底层实现。结语test_layout_fail.py::VisualLayoutFailureTests::test_xkcd_logo_change这份用例计划虽然只有两行表格却浓缩了 SeleniumBase 视觉回归测试的完整闭环baselineTrue建基线 →set_attribute()制造差异 →level3最严格比对 → 测试失败并产出side_by_side.html报告。理解这套机制后你就能把它迁移到自己的业务页面上建立基线、模拟元素变动resize、remove、属性改写、选择合适的 level 分级并在站点真实改版时用--visual_baseline干净地重置基线。【免费下载链接】SeleniumBaseAPIs for browser automation, testing, and bypassing bot-detection. Includes CDP Mode: A stealthy configuration for chromium that passes every bot detection test.项目地址: https://gitcode.com/GitHub_Trending/se/SeleniumBase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考