Selenium 浏览器 Profile 集成与会话归属
用 Selenium 启动浏览器 profile、隔离存储,并在获准测试中可靠关闭和恢复会话。
Selenium 通过 WebDriver 标准控制浏览器。Profile 为会话添加浏览器状态和配置,因此集成不只是选择 executable。测试 runner 必须负责完整会话的启动、存储目录、网络策略、清理和证据。明确归属可防止两个 worker 同时写入同一 profile,也让失败更容易重现。
浏览器 profile 不能保证网站接受自动任务,Selenium 也不会改变网站访问规则。只在自有或获准测试的应用中使用。启动前定义用户任务和预期结果,不把凭据写入 fixture,并在应用报告访问或策略边界时停止。
可靠的设置由一个 runner、一个活动浏览器进程和一个 profile 所有者组成。持久存储是产品选择,不是默认要求。短期功能测试可以使用隔离的临时目录;连续性测试可以在提前确定保留、访问和删除规则后使用受管持久目录。把这个决定写清楚。
确定浏览器启动的所有者
Selenium 可以通过 driver 服务和浏览器专用选项启动浏览器。同一机器安装多个浏览器时,runner 应明确选择目标 binary。测试结果记录浏览器版本、driver 版本、runner 修订和选中的 binary。这样的身份信息比依赖系统路径中偶然排在前面的 executable 更有用。Selenium 的 Chrome 官方示例说明了浏览器程序选择与参数设置,但不能证明所有定制浏览器都兼容。
最小启动示例
下面的 Python 示例明确选择一个浏览器 binary 和一个隔离的 Chromium user-data 目录。请把两个路径替换为 runner 上受管的本地路径,并且只访问获准测试的应用。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.binary_location = "/path/to/approved/browser"
options.add_argument("--user-data-dir=/path/to/browser-state")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://app.example.test/settings")
assert driver.current_url.startswith("https://app.example.test/")
finally:
driver.quit()
User-data 目录保存 Chromium 运行时状态,独立的浏览器 profile 配置描述本次 session 选择的浏览器行为。本示例只演示 Selenium 和 Chromium user-data 的归属。应用若另有浏览器 profile 配置,只能通过该产品已说明的集成入口传入;不要从本示例猜测选项,不要让两个输入指向同一路径,也不要把配置材料复制进 user-data 目录。
Driver 与浏览器需要兼容,才能建立 WebDriver 会话。版本发现工具可以提供帮助,受管环境通常会固定两者以便重现。如果会话创建失败,先确认选中的 binary 和 driver,再考虑 profile。启动层的不匹配不能通过修改 cookie、locale 或存储状态来修复。
进程生命周期只能由一层负责。Runner 启动 driver,driver 按批准设计启动或连接目标浏览器,同一 runner 再关闭会话。不要在未说明边界时混用手工启动的浏览器、自动管理的 driver 和第二套清理脚本。分裂的归属容易在失败后遗留进程或存储锁。
远程 Selenium 部署还增加了宿主边界。Profile 目录必须存在于实际运行浏览器的节点,而不只是发送命令的机器。Binary 路径、下载、证书和网络设置也由该节点解释。Grid 应提供稳定的节点能力和存储策略,不应传递对远端毫无意义的本地工作站路径。
重试前要分类启动失败。区分 binary 不可用、driver 不兼容、profile 目录不可读、已有 profile 锁,以及浏览器启动时退出。每种情况的责任方不同。输入未变化时重复启动只会产生更多孤立进程,不会增加证据。
安全控制也属于启动合同。测试应保留浏览器的正常进程隔离和部署要求的宿主控制。不要为了启动会话而降低 sandbox、文件权限或证书验证。环境无法满足浏览器前提时,应把设置标记为不支持并修复宿主镜像。秘密放在平台凭据存储中,运行记录只说明认证可用,不复制密码或恢复码。
设置清晰的 Profile 与存储边界
Chromium profile 目录包含偏好、存储数据库、缓存、扩展状态和其他浏览器管理的文件。它不是可随意编辑的单文件,浏览器拥有目录期间不应修改它。每个并发会话都使用不同目录。多个 worker 共享目录会破坏状态、触发锁错误,并让结果取决于时序而非被测应用。Chromium 用户数据目录文档区分了用户数据目录与其内部的配置子目录,并说明启动参数;独立的产品配置不能与这些目录互换。
根据任务选择临时或持久存储。临时存储适合从已知空状态开始的测试,例如首次运行界面或 consent 行为。持久存储适合获准的连续性测试,在重启后保留同一用户关系。持久目录需要所有者、保留期、访问控制、备份决定和已说明的重置步骤。
不要复制仍被使用的 profile 目录。先正常关闭浏览器,再复制受管 fixture,并把副本作为具有独立标识的新测试资产。扩大使用前确认副本可以成功打开。Fixture 若包含账户状态或个人数据,应换成合成账户;确需使用时必须获得明确授权并应用常规删除策略。
浏览器存储可能比创建它的测试存在更久。Cookie、local storage、service worker 数据、permission 和下载历史都可能影响下一次运行。记录哪些元素应当保留。测试失败后不要自动清空目录,因为清理可能删除理解用户可见状态所需的证据。先停止复用、保存最小结果,再按策略重置或退役。
Profile 配置与用户数据不能混为一体。可复用配置可以描述 locale、网络策略和支持的浏览器族,而不携带真实用户浏览历史。Profile 材料、测试凭据、应用 fixture 和运行输出应使用不同存储位置与访问规则。浏览器 profile 管理指南提供了更完整的生命周期模型。
文件系统行为也会影响可靠性。本地磁盘、网络卷和容器挂载路径在锁、延迟、所有权和清理语义上可能不同。验证生产实际使用的存储类别,不要假设工作站上的 fixture 在远程节点表现相同。为浏览器数据库和下载保留足够空间,把卷已满归为测试基础设施失败。持久 profile 只能在浏览器关闭时备份。
对齐网络、Locale 与应用上下文
在浏览器启动前设定网络和 locale。会话不应在一条路由下导航后,保留相同应用状态却静默切换另一条路由。测试需要代理时,使用浏览器获准的网络路径,并通过自有端点验证。Selenium 日志、截图和报告中不要出现代理凭据或完整连接字符串。
Locale 不只是界面语言。应用行为还可能依赖语言偏好、timezone、键盘输入、日期格式和测试账户的地区数据。说明用户流程需要的值,并让它们与网络上下文相容。应用支持多个地区时,使用不同 profile 或会话,避免 cookie 和已存选择在地区案例间交叉。
Selenium capability 描述会话如何启动,但不应变成未经审查的 flags 集合。为每个支持环境维护少量有所有者的配置,删除不再服务于已说明要求的选项,并在浏览器或 driver 更新后验证完整流程。能成功启动的配置仍可能不适用于下载、通知、媒体 permission 或长任务。
应用状态也需要所有者。尽量使用合成测试账户,将每个账户隔离到预定 profile,并在产品不支持时避免并行使用同一账户。把登录、退出、consent 和账户删除做成明确测试步骤,而不是隐藏准备。密码和 session token 不得保存在公开报告或版本控制 fixture 中。
自动化框架差异应留在集成边界。Selenium 任务使用 WebDriver 概念和生命周期,而不是模仿另一框架的 context 模型。需要比较时可分别查看 Playwright profile 指南和 Puppeteer profile 指南。控制库变化时,应用验收标准应保持相同。
验证自有应用的用户流程
从一个用户可见任务开始,例如打开设置页面、提交合成表单、下载自有报告或恢复获准会话。定义起始状态、预期屏幕、允许的网络边界和完成信号。只证明会话创建,并不能证明 profile 支持预定流程。
断言应对应应用,而不是偶然的浏览器内部信息。确认预期页面显示、选择的语言生效、要求保留的偏好持续存在,以及用户可见错误得到处理。不要收集任务不需要的大量浏览器属性。范围较窄的证据更易审查,也暴露更少测试环境信息。
包括负面和恢复路径。在适用处测试无效表单值、拒绝可选 permission、中断导航、缺失下载目录和主动取消。安全重试时保留用户输入,并确认失败动作不会被记录为完成。重试应从已知应用状态开始,而不是沿用前一个异常留下的任意状态。
截图和日志可能包含账户名、文档标题、消息或本地路径。只有断言需要时才采集,遮蔽敏感字段并设置删除期。优先使用包含测试名、应用修订、浏览器身份和结果的结构化记录。自有 fixture 的小段 DOM 往往比整页截图更有用且更少敏感内容。
连续性是要求时,在干净 profile 与受管持久 profile 中运行同一流程。干净运行显示应用是否依赖未声明状态;持久运行显示预期 preference 和 session 是否保留。差异应以应用任务解释,而不是承诺所有网站都采用相同行为。
等待条件应表示应用事件,而不是任意暂停。使用导航完成、提交控件启用、下载结束或 accessible 状态消息等可见条件。设定符合自有应用服务目标的有限超时,并报告哪个条件未满足。固定延迟可能在快节点通过、在普通负载失败,无限等待则会永久占用 profile。
关闭会话并从失败恢复
测试结束时始终请求正常的 WebDriver 关闭。干净关闭让浏览器刷新受管存储并释放 profile 锁。确认会话结束后再复用或复制目录。强制终止只应作为 runner 已记录失败阶段后的异常恢复动作,不应成为每次测试的标准结尾。WebDriver 的 Delete Session 命令关闭活动会话;成功响应本身不能证明应用已完成下载或上传。
Runner 也要处理自身中断。如果测试进程停止,supervisor 可以识别该运行创建的 driver 和浏览器进程,并在归属解决前将 profile 标记为不可用。不要终止共享宿主上的无关浏览器进程。使用运行专属标识和有限清理策略,避免恢复影响另一 worker。
下载、上传和后台工作可能在可见断言后继续。为每种任务定义完成条件。只有浏览器与应用都报告完成且文件稳定,下载才完成;只有自有应用确认接收,上传才完成。达到这些条件后关闭会话,或明确取消任务,避免下一测试继承未完成活动。
浏览器意外退出时,保存最小失败包:runner 修订、binary、driver 版本、profile 标识、最后完成的应用步骤和已遮蔽错误。默认不要复制整个 profile。先用合成 fixture 或干净 profile 重现,只有较小记录无法解释且授权允许时才升级访问原目录。
Profile 重置应当确定。明确重置意味着删除临时目录、恢复已知 fixture,还是创建新的持久身份。不要只删除部分浏览器数据库而保留相关状态。对受管持久 profile,退役通常比手术式清理更安全。记录退役原因,并按数据策略移除目录。
自动化失败时也要保留可访问性状态。被测应用移动 focus、打开 dialog 或显示进度时,应断言键盘和辅助技术用户获得同样的完成或错误信息。Selenium exception 不能说明用户看到了什么。保留应用状态到捕获 accessible 结果,再关闭会话并删除不必要内容。
按阶段排查问题
会话创建失败时先检查启动归属:binary、driver 兼容、节点可用性、目录 permission 和 profile 锁。导航失败时检查获准网络路径和自有应用响应。UI 状态不正确时检查 locale、账户 fixture 和已存应用数据。分开阶段可以防止无关修改掩盖原问题。
浏览器和 driver 更新应与应用一起审查。固定已知可用的组合获得可重复运行,然后在小型自有流程中测试更新,再扩大部署。行为变化时使用相同 profile fixture 和应用修订比较。浏览器版本验证指南说明如何区分 runtime、依赖和应用变化。
远程节点还涉及容量与调度。节点不应接收超出 memory、storage 和 process 限制的活动 profile。应排队,而不是共享 profile 或让资源压力决定哪个测试失败。记录节点类别和工作量即可,不要公开内部主机名、地址或目录布局。
并行执行只能在单会话已可重复后引入。为每个 worker 分配唯一 profile、下载目录、端口、应用账户和运行标识。根据已测宿主容量限制并发,并保留一个串行运行用于诊断。若失败只在负载下出现,先比较资源压力和应用时序,再更改浏览器配置。Artifact 使用运行标识,避免不同 worker 的截图、下载和日志被意外合并。
所有可以脱离报告单独保存的 artifact 都应带有运行标识,例如下载文件或浏览器 console 片段。这样删除一次运行时不会碰到其他 worker 的证据。
Profile 退役时通知应用账户所有者和依赖它的测试排程。新 profile 应有新的标识和明确的起始状态,不应静默继承旧假设。
如果测试因为应用状态而停止,记录用户可见的暂停原因和恢复动作。不要把 runner 的异常描述成用户已经完成了任务。
有用的支持报告应说明受影响的用户流程、失败阶段、浏览器与 driver 身份、profile 存储模式和下一安全动作。不要承诺普遍兼容,也不要声称自动化与手工浏览不可区分。Selenium 为获准测试提供浏览器控制,可靠性来自明确归属、隔离状态、受控证据和干净关闭。