Python + Playwright + Pytest 面试题
Python + Playwright + Pytest 面试题
自动化测试技术栈中最核心的三件套,也是面试技术考察的重点。
本文正在根据真实项目经验整理,后续持续补充。
Python + Playwright + Pytest 面试题与结构化回答话术
适用岗位:UI 自动化测试、测试开发、自动化测试工程师
建议回答结构:先说结论 → 说明原理 → 介绍实际做法 → 结合项目举例 → 补充风险和边界
高频等级说明
| 星级 | 等级 | 学习要求 |
|---|---|---|
| ★★★★★ | 必问 | 必须能够熟练、结构化回答,并准备项目案例 |
| ★★★★☆ | 高频 | 需要重点掌握,能够结合实际项目回答 |
| ★★★☆☆ | 常见 | 理解原理,能够说清核心做法 |
| ★★☆☆☆ | 进阶 | 针对中高级岗位进行准备 |
| ★☆☆☆☆ | 扩展 | 了解即可,根据岗位方向选择准备 |
★★★★★ 五星必问题速查
- Python 为什么适合自动化测试?
- 如何处理 Python 异常?
- Python 如何连接数据库并校验数据?
- 为什么选择 Playwright,而不是 Selenium?
- Playwright 的 Browser、Context 和 Page 是什么?
- Playwright 的自动等待机制是什么?
- 如何设计稳定的元素定位器?
- 如何复用登录状态?
- 如何监听接口响应并做断言?
- 什么是 fixture?
- 如何实现参数化测试?
- 如何实现并行执行?
- 如何在失败时自动截图并保存 Trace?
- 你的 UI 自动化框架是如何设计的?
- 如何介绍你做过的 Python + Playwright + Pytest 项目?
面试题总目录
一、Python 自动化基础
- Python 为什么适合自动化测试? ★★★★★
- 列表、元组、字典和集合有什么区别? ★★★★☆
- 深拷贝和浅拷贝有什么区别? ★★★★☆
- Python 中
*args和**kwargs有什么作用? ★★★☆☆ - 什么是装饰器?自动化测试中如何使用? ★★★★☆
- 如何处理 Python 异常? ★★★★★
- 什么是生成器? ★★★☆☆
- 类方法、静态方法和实例方法有什么区别? ★★★☆☆
- 如何读取 YAML、JSON 和 Excel 测试数据? ★★★★☆
- Python 如何连接数据库并校验数据? ★★★★★
二、Playwright 核心能力
2.1 为什么选择 Playwright,而不是 Selenium? ★★★★★
2.2 Playwright 的 Browser、Context 和 Page 是什么? ★★★★★
2.3 Playwright 的自动等待机制是什么? ★★★★★
2.4 Playwright 常用定位方式有哪些? ★★★★★
2.5 如何设计稳定的元素定位器? ★★★★★
2.6 为什么不建议大量使用 wait_for_timeout? ★★★★★
2.7 如何处理新窗口和多标签页? ★★★★☆
2.8 如何处理 iframe? ★★★★☆
2.9 如何处理弹窗、文件上传和文件下载? ★★★★☆
2.10 如何复用登录状态? ★★★★★
2.11 如何拦截和修改网络请求? ★★★★☆
2.12 如何监听接口响应并做断言? ★★★★★
2.13 如何处理动态表格和虚拟滚动表格? ★★★★★
2.14 如何处理遮罩层、动画和偶发点击失败? ★★★★★
2.15 Playwright 的 Trace 有什么作用? ★★★★★
三、Pytest 核心能力
3.1 Pytest 相比 unittest 有什么优势? ★★★★★
3.2 什么是 fixture? ★★★★★
3.3 fixture 有哪些作用域? ★★★★☆
3.4 yield fixture 有什么作用? ★★★★☆
3.5 conftest.py 有什么作用? ★★★★★
3.6 如何实现参数化测试? ★★★★★
3.7 如何给用例分类并按需执行? ★★★★☆
3.8 如何控制用例执行顺序? ★★★★☆
3.9 如何实现失败重跑? ★★★★☆
3.10 如何实现并行执行? ★★★★★
3.11 如何跳过用例和设置预期失败? ★★★☆☆
3.12 Pytest 常用钩子函数有哪些? ★★★★☆
3.13 如何在失败时自动截图并保存 Trace? ★★★★★
3.14 如何把 Pytest 与 Allure 结合? ★★★★★
3.15 如何处理用例之间的数据依赖? ★★★★★
四、框架设计与项目实战
4.1 你的 UI 自动化框架是如何设计的? ★★★★★
4.2 Page Object 模式是什么? ★★★★★
4.3 页面对象层和业务流程层如何划分? ★★★★★
4.4 自动化测试如何实现数据驱动? ★★★★★
4.5 UI 自动化应该断言什么? ★★★★★
4.6 页面、接口和数据库结果不一致时如何定位? ★★★★★
4.7 如何降低 UI 自动化用例的维护成本? ★★★★★
4.8 自动化用例偶发失败如何治理? ★★★★★
4.9 如何接入 Jenkins 持续集成? ★★★★★
4.10 如何介绍你做过的 Python + Playwright + Pytest 项目? ★★★★★
一、Python 自动化基础
1.1 Python 为什么适合自动化测试? ★★★★★ 必问
考察点: 是否理解语言选择与测试工程效率之间的关系。
结构化回答话术:
Python 语法简洁、学习成本较低,并且拥有完善的自动化测试生态,例如 Pytest、Playwright、Requests、Pandas 和数据库驱动。它既可以完成 UI 和接口自动化,也可以处理 Excel、JSON、日志和数据库数据,适合快速搭建测试框架。
在我的项目中,我使用 Python + Playwright 编写 UI 自动化,用 Pytest 管理用例和参数化,再结合 Allure 和 Jenkins 实现定时回归。Python 的价值不只是"代码少",更重要的是能够把浏览器操作、数据处理、断言和持续集成串成完整流程。
可能追问: Python 的性能不如 Java,会影响自动化测试吗?
追问回答: 大多数 UI 自动化的主要耗时在浏览器、网络和服务端响应,而不是 Python 本身。除非有大量 CPU 密集型计算,否则 Python 的性能通常不会成为 UI 测试瓶颈。
1.2 列表、元组、字典和集合有什么区别? ★★★★☆ 高频
考察点: 是否理解四种核心数据结构的特性与适用场景,能否在测试中正确选择数据类型。
结构化回答话术:
列表有序且可修改,适合保存一组可变化的数据;元组有序但不可修改,适合表示相对固定的数据;字典使用键值对存储,适合保存测试用例参数和接口响应;集合中的元素唯一,适合去重和集合比较。
例如,我会使用字典保存一条测试数据,使用列表保存多条场景,使用集合比较页面和数据库返回的业务主键是否一致。
1.3 深拷贝和浅拷贝有什么区别? ★★★★☆ 高频
考察点: 是否理解对象复制时的引用共享问题,能否避免测试数据被意外修改。
结构化回答话术:
浅拷贝只复制最外层对象,嵌套的可变对象仍然共享引用;深拷贝会递归复制所有层级。测试数据中如果存在嵌套字典或列表,使用浅拷贝后修改子对象,可能污染原始数据并影响其他用例。
在参数化场景中,如果我要基于公共模板生成多组互不影响的请求数据,会使用 copy.deepcopy(),避免用例之间相互修改数据。
1.4 Python 中 *args 和 **kwargs 有什么作用? ★★★☆☆ 常见
考察点: 是否理解不定参数的使用场景,能否在封装通用方法时正确使用。
结构化回答话术:
*args 用于接收不定数量的位置参数,函数内部得到一个元组;**kwargs 用于接收不定数量的关键字参数,函数内部得到一个字典。它们常用于封装通用方法和装饰器。
例如,封装日志装饰器时,不同页面方法的参数数量并不一致,就可以通过 *args 和 **kwargs 统一接收并透传参数。
1.5 什么是装饰器?自动化测试中如何使用? ★★★★☆ 高频
考察点: 是否理解装饰器的原理,能够在日志、重试和计时等场景合理使用。
结构化回答话术:
装饰器是在不修改原函数主体的情况下扩展函数行为的机制。自动化测试中可以用于日志记录、执行耗时统计、截图、权限校验和有限重试。
我会谨慎使用重试装饰器。只有明确属于网络波动或环境抖动的操作才允许有限重试,并且每次失败都要保留日志;不能用重试掩盖真实缺陷或不稳定定位器。
1.6 如何处理 Python 异常? ★★★★★ 必问
考察点: 是否掌握异常处理的最佳实践,能否在自动化中正确处理失败并保留证据。
结构化回答话术:
Python 通过 try、except、else、finally 处理异常。我的原则是只捕获能够明确处理的异常,不使用空的 except 把所有错误吞掉;发生异常时记录页面、参数、堆栈和关键日志,资源清理放在 finally 或 fixture 的清理阶段。
例如,页面点击失败时,我不会简单返回 False,而是保留截图和 Trace,再抛出带业务上下文的异常,让 Pytest 正确标记用例失败。
1.7 什么是生成器? ★★★☆☆ 常见
考察点: 是否理解生成器按需生成数据的特点及其在测试中的适用场景。
结构化回答话术:
生成器通过 yield 按需产生数据,不会一次性把全部数据加载到内存中,适合处理大量数据或流式结果。它保留上一次执行状态,下次迭代时继续执行。
在测试中,如果数据库查询或文件中有大量记录,可以使用生成器逐条处理,降低内存占用。不过普通的小规模参数化数据直接使用列表会更清晰。
1.8 类方法、静态方法和实例方法有什么区别? ★★★☆☆ 常见
考察点: 是否理解三种方法的区别及在 Page Object 设计中的合理使用。
结构化回答话术:
实例方法的第一个参数是 self,可以访问实例属性;类方法使用 @classmethod,第一个参数是 cls,适合创建不同配置的对象;静态方法使用 @staticmethod,不依赖实例或类状态,适合放置与该类相关的纯工具逻辑。
Page Object 中页面操作通常使用实例方法,因为它需要访问当前 Page;格式转换等无状态方法可以设计为静态方法。
1.9 如何读取 YAML、JSON 和 Excel 测试数据? ★★★★☆ 高频
考察点: 是否掌握多种数据格式的读取方式,以及读取后的校验和转换。
结构化回答话术:
JSON 适合结构明确的数据交换和基准文件;YAML 可读性好,适合配置环境、页面和任务;Excel 适合业务人员维护表格型场景。读取后需要进行字段校验、类型转换、必填检查和默认值处理,不能直接把外部数据传给测试逻辑。
我的项目中使用 Excel 维护场景类型、配对 ID 和指令序号,再转换成统一的数据对象供 Pytest 参数化使用;对于金额和日期还会在读取阶段做标准化。
1.10 Python 如何连接数据库并校验数据? ★★★★★ 必问
考察点: 是否掌握数据库连接、查询和数据校验的基本方法,理解安全与数据一致性要求。
结构化回答话术:
根据数据库类型选择驱动,建立连接后使用参数化 SQL 查询,获取结果并转换为统一结构,再与页面或接口数据比较。查询完成后要关闭游标和连接,账号密码通过环境变量或密钥管理注入。
数据库断言不能只判断"查到了数据",还要根据业务主键验证状态、金额、时间和关联关系。对于最终一致性场景,可以在明确超时时间内轮询,但要保留每次查询结果,不能无限等待。
二、Playwright 核心能力
2.1 为什么选择 Playwright,而不是 Selenium? ★★★★★ 必问
考察点: 是否理解两款工具的核心差异,能够根据项目特点做出合理选型。
结构化回答话术:
Playwright 对现代 Web 应用支持较好,内置自动等待、浏览器上下文、网络拦截、Trace、视频和多标签页能力,并且同时支持 Chromium、Firefox 和 WebKit。它减少了大量显式等待和浏览器驱动管理代码。
不过我不会简单说 Playwright 一定比 Selenium 好。已有成熟 Selenium 体系的项目不一定需要迁移;新项目如果前端交互复杂、需要网络监听和并发隔离,Playwright 通常更合适。
2.2 Playwright 的 Browser、Context 和 Page 是什么? ★★★★★ 必问
考察点: 是否理解三层模型的设计思想,能否在框架中合理利用 Context 实现会话隔离。
结构化回答话术:
Browser 表示浏览器进程;BrowserContext 是相互隔离的浏览器会话,拥有独立的 Cookie、Local Storage 和权限;Page 表示一个页面或标签页。
实际框架中通常不需要每条用例都启动一个浏览器进程,而是在同一个 Browser 下创建不同 Context,实现较低成本的会话隔离。不同账号或并行用例使用独立 Context,可以避免登录状态和测试数据互相污染。
2.3 Playwright 的自动等待机制是什么? ★★★★★ 必问
考察点: 是否理解自动等待的原理,能否区分自动等待与业务状态等待的不同用途。
结构化回答话术:
Playwright 在执行点击、输入等操作前,会自动检查元素是否存在、可见、稳定、可接收事件以及是否启用;断言也会在超时时间内自动重试,直到满足条件或超时。
自动等待能减少固定休眠,但不能代替业务状态等待。例如提交交易后需要等待后端处理完成,我会等待明确的接口响应、状态文本或数据库状态,而不是认为元素能点击就表示业务已完成。
2.4 Playwright 常用定位方式有哪些? ★★★★★ 必问
考察点: 是否掌握 Playwright 定位器的优先级和选择策略。
结构化回答话术:
优先使用面向用户和可访问性的定位方式,如 get_by_role、get_by_label、get_by_placeholder 和 get_by_text;测试系统如果提供稳定的 data-testid,也可以使用 get_by_test_id。CSS 和 XPath 作为补充。
定位器应该体现元素的业务语义,避免依赖容易变化的层级、序号和动态 class。定位后还要保证唯一性,不能因为当前页面碰巧只有一个元素就忽略歧义。
2.5 如何设计稳定的元素定位器? ★★★★★ 必问
考察点: 是否具备定位器稳定性设计的实战经验和维护策略。
结构化回答话术:
我会按照稳定性排序选择定位器:稳定测试属性、角色与名称、表单标签、稳定文本、稳定 CSS,最后才是 XPath。对于表格行,会先通过业务主键定位目标行,再在行内定位按钮,而不是使用固定的第几行。
如果定位器经常变化,我会推动开发增加 data-testid,并把定位器集中在 Page Object 中维护,避免散落在测试用例里。
2.6 为什么不建议大量使用 wait_for_timeout? ★★★★★ 必问
考察点: 是否理解固定等待与条件等待的本质区别,能否写出稳定的等待逻辑。
结构化回答话术:
固定等待无法判断页面何时真正完成,等待过短会偶发失败,等待过长会降低执行效率。更合理的方式是等待明确条件,例如元素可见、接口响应完成、按钮可用或业务状态变化。
固定等待只适合临时调试,或者系统确实没有任何可观察状态的极少数场景;进入正式框架前应尽量替换为条件等待。
2.7 如何处理新窗口和多标签页? ★★★★☆ 高频
考察点: 是否掌握 Playwright 多页面管理机制,能否正确处理页面切换。
结构化回答话术:
点击前先注册新页面事件等待,再执行触发操作并获取新 Page,之后等待页面达到可操作状态。不能先点击再监听,否则可能错过事件。
处理完成后要根据业务决定关闭新页还是切回原页,并避免使用页面数组的固定序号,因为并发或系统弹窗可能改变顺序。
2.8 如何处理 iframe? ★★★★☆ 高频
考察点: 是否掌握 iframe 内元素的定位方法和跨域场景的处理策略。
结构化回答话术:
使用 frame_locator() 定位 iframe,再在对应 FrameLocator 内查找元素。首先要确认元素确实位于 iframe 中,并使用 iframe 的稳定属性定位。
如果 iframe 跨域,Playwright 仍可以通过 frame API 操作页面内容,但系统的权限、加载失败和第三方服务稳定性仍要单独考虑。
2.9 如何处理弹窗、文件上传和文件下载? ★★★★☆ 高频
考察点: 是否掌握常见的特殊交互处理方式,能够验证操作结果。
结构化回答话术:
浏览器原生对话框通过 dialog 事件处理;文件上传优先对文件输入框使用 set_input_files;下载需要先等待 download 事件,再执行触发下载的操作,最后保存文件并校验文件名、大小和内容。
如果导出的是 Excel 或 CSV,我不会只判断下载成功,还会读取文件并验证关键字段、行数和金额汇总。
2.10 如何复用登录状态? ★★★★★ 必问
考察点: 是否掌握 storage_state 的使用方式和安全注意事项。
结构化回答话术:
登录成功后可以通过 storage_state 保存 Cookie 和 Local Storage,新建 Context 时加载该状态,减少重复登录。状态文件不能提交真实账号信息,并且需要考虑过期、环境隔离和账号权限差异。
在框架中我会先验证复用后的会话是否有效,失效时重新登录并更新状态,而不是所有失败都默认归因于页面元素。
2.11 如何拦截和修改网络请求? ★★★★☆ 高频
考察点: 是否掌握 route 拦截的使用场景和 Mock 策略。
结构化回答话术:
可以通过 page.route() 拦截请求,选择继续、终止、修改请求或返回 Mock 响应。常用于隔离不稳定的第三方服务、构造异常响应和验证前端容错。
Mock 不能替代真实接口联调。我的做法是让 Mock 测试验证前端分支和异常处理,再保留真实环境端到端用例验证完整链路。
2.12 如何监听接口响应并做断言? ★★★★★ 必问
考察点: 是否掌握 expect_response 的使用方式,能够在 UI 操作中同步验证接口。
结构化回答话术:
在触发页面操作前使用 expect_response 等待目标接口,触发操作后获取响应,再校验状态码、业务码和关键字段。接口识别不能只匹配模糊 URL,最好同时结合请求方法、路径和必要参数。
这样可以把"按钮点了以后页面没变化"进一步定位为前端未发请求、接口失败、返回数据错误或页面渲染错误。
2.13 如何处理动态表格和虚拟滚动表格? ★★★★★ 必问
考察点: 是否具备复杂表格场景的数据采集和校验能力。
结构化回答话术:
动态表格要通过业务主键定位行,并处理分页、排序和异步加载。虚拟滚动表格只渲染可视区域,不能直接认为 DOM 中的行就是全部数据,需要循环滚动、采集当前可见行并按主键去重。
我在交易台账的 ag-grid 场景中处理过横向滚动:先读取固定列和业务主键,再横向滚动采集其他列,最终按主键合并并与预期数据比较。
2.14 如何处理遮罩层、动画和偶发点击失败? ★★★★★ 必问
考察点: 是否具备处理页面动态干扰因素的能力,能否合理使用兜底策略。
结构化回答话术:
先通过截图、Trace 和 DOM 状态确认是遮罩、动画、元素未稳定、重复元素还是业务状态未完成。然后等待遮罩消失或目标元素可操作,必要时修改定位范围。
我不会一开始就使用强制点击,因为它可能绕过真实的页面交互问题。只有确认遮挡属于无业务意义的框架缺陷,并保留证据后,才考虑有限兜底。
2.15 Playwright 的 Trace 有什么作用? ★★★★★ 必问
考察点: 是否理解 Trace 的组成以及在失败定位中的价值。
结构化回答话术:
Trace 可以记录测试过程中的页面快照、操作、网络请求、控制台信息和时间线。它比单张失败截图更适合分析"失败前发生了什么"。
我会在 CI 中按失败保留 Trace,同时保存截图、日志和必要的视频。这样可以区分页面定位问题、接口异常、环境波动和脚本逻辑问题,减少远程环境中无法复现的情况。
三、Pytest 核心能力
3.1 Pytest 相比 unittest 有什么优势? ★★★★★ 必问
考察点: 是否理解 Pytest 的核心优势,能够说清选型原因。
结构化回答话术:
Pytest 语法更简洁,支持普通 assert、fixture、参数化、marker、插件和钩子机制,适合搭建可扩展的自动化框架。它也可以兼容部分 unittest 用例。
我选择 Pytest 主要不是因为写法短,而是 fixture 能清晰管理浏览器、账号、数据和清理逻辑,插件生态还能支持并发、重跑和 Allure 报告。
3.2 什么是 fixture? ★★★★★ 必问
考察点: 是否理解 fixture 的依赖注入机制和在自动化中的核心作用。
结构化回答话术:
fixture 是 Pytest 提供的测试依赖和资源管理机制,可以完成前置准备、依赖注入和后置清理。用例只需要声明参数名,Pytest 会自动找到并执行对应 fixture。
在 UI 自动化中,我会用 fixture 管理 Browser、Context、Page、登录账号、测试数据和失败产物,避免在每条用例中重复编写初始化代码。
3.3 fixture 有哪些作用域? ★★★★☆ 高频
考察点: 是否理解不同作用域的性能和隔离权衡。
结构化回答话术:
常见作用域包括 function、class、module、package 和 session。function 每条用例执行一次,隔离性最好;session 整个测试会话执行一次,适合浏览器进程或全局配置。
作用域不能一味设大来追求速度。页面状态和测试数据如果需要隔离,应使用 function 级 Context;Browser 可以使用 session 级,以兼顾性能和隔离。
3.4 yield fixture 有什么作用? ★★★★☆ 高频
考察点: 是否理解 yield 的前后置分离机制和清理可靠性。
结构化回答话术:
yield 之前执行初始化并把资源提供给用例,yield 之后执行清理。即使用例失败,清理逻辑通常仍会执行。
例如创建测试数据后 yield 给用例使用,测试结束后删除数据;创建 Context 后交给用例,结束后关闭 Context。清理失败也要记录,但不能覆盖原始用例失败。
3.5 conftest.py 有什么作用? ★★★★★ 必问
考察点: 是否理解 conftest 的作用域和职责划分。
结构化回答话术:
conftest.py 用于存放目录范围内共享的 fixture 和钩子,不需要显式导入,Pytest 会自动发现。它适合管理浏览器、环境配置、账号和公共测试资源。
但不能把所有业务逻辑都堆在 conftest.py 中。通用资源放 fixture,页面操作放 Page Object,业务流程放 service 或 workflow,断言放独立验证层,职责要清晰。
3.6 如何实现参数化测试? ★★★★★ 必问
考察点: 是否掌握多种参数化方式,能够为不同场景选择合适的实现。
结构化回答话术:
常用方式是 @pytest.mark.parametrize,也可以通过 fixture 参数、pytest_generate_tests 或外部数据文件动态生成。参数化数据应包含清晰的 id,这样报告能直接看出失败的是哪个场景。
在金融交易项目中,我使用 Excel 管理业务类型、场景类型、配对 ID 和指令序号,读取后转换成统一数据结构,再传给 Pytest 执行相同流程下的不同业务组合。
3.7 如何给用例分类并按需执行? ★★★★☆ 高频
考察点: 是否理解 marker 的使用和命令行筛选机制。
结构化回答话术:
使用 marker 给用例标记 smoke、regression、module、province 等分类,并在配置中注册,执行时通过 -m 选择。也可以结合命令行参数按环境、模块、账号或场景筛选。
我会让 Jenkins 将这些参数暴露为构建参数,实现冒烟、全量回归和指定业务模块按需执行。
3.8 如何控制用例执行顺序? ★★★★☆ 高频
考察点: 是否理解用例独立性原则,以及在必须串联时的正确做法。
结构化回答话术:
优先让用例彼此独立,而不是依赖固定执行顺序。如果业务确实是申请、审批、查询的连续流程,我会把它设计成一条完整业务用例,或者通过 fixture 显式传递业务数据。
依赖插件强制排序只能解决表面问题,容易导致单独运行失败和并行执行困难,因此不应成为默认方案。
3.9 如何实现失败重跑? ★★★★☆ 高频
考察点: 是否理解重跑的正确使用方式和适用边界。
结构化回答话术:
可以使用 pytest-rerunfailures 对失败用例设置有限次数重跑,也可以只对明确的异常类型或标记用例重跑。报告中必须保留首次失败及重跑信息。
重跑是处理环境瞬时波动的兜底,不是解决脚本不稳定的方法。如果同一用例经常靠重跑通过,应统计失败原因并治理定位器、等待条件、数据和环境。
3.10 如何实现并行执行? ★★★★★ 必问
考察点: 是否掌握 pytest-xdist 的使用及并行执行的数据隔离。
结构化回答话术:
可以使用 pytest-xdist 通过多个 worker 并行执行。并行前必须保证账号、Context、测试数据、下载目录、日志和报告文件相互隔离。
并行不是简单加 -n auto。如果多个用例操作同一笔业务数据或共享账号状态,容易互相影响。我会先识别共享资源,按 worker 分配账号和数据,再逐步提高并发度。
3.11 如何跳过用例和设置预期失败? ★★★☆☆ 常见
考察点: 是否理解 skip 和 xfail 的使用场景及管理规范。
结构化回答话术:
使用 skip 或 skipif 跳过暂时不适用的场景,使用 xfail 标记已知缺陷或暂未实现功能。所有跳过和预期失败都要有明确原因、关联问题和清理计划。
不能长期用 skip 隐藏失败,也不能把真实回归缺陷直接改成 xfail 来让流水线变绿。
3.12 Pytest 常用钩子函数有哪些? ★★★★☆ 高频
考察点: 是否理解钩子机制并在实际项目中使用过。
结构化回答话术:
常用钩子包括 pytest_addoption 增加命令行参数、pytest_configure 完成初始化配置、pytest_collection_modifyitems 修改收集结果、pytest_runtest_makereport 获取各阶段执行结果。
我通常通过 pytest_runtest_makereport 判断用例是否在执行阶段失败,然后触发截图、Trace 和日志保存。
3.13 如何在失败时自动截图并保存 Trace? ★★★★★ 必问
考察点: 是否掌握失败证据自动采集的完整实现方案。
结构化回答话术:
通过 fixture 管理 Page 和 Trace,在钩子中获取用例执行结果。发生失败时,以用例名称、时间和 worker 标识生成唯一目录,保存页面截图、HTML、控制台信息和 Trace;测试结束后关闭资源。
失败产物应关联到 Allure 或 CI 构建中,并注意敏感数据脱敏。截图成功不能影响原始异常,保存产物失败时也要记录独立日志。
3.14 如何把 Pytest 与 Allure 结合? ★★★★★ 必问
考察点: 是否能够使用 Allure 组织报告结构并关联失败证据。
结构化回答话术:
使用 Allure Pytest 插件生成结果文件,再由 Allure 命令生成报告。可以通过 feature、story、title、severity 和 step 组织用例,并把截图、Trace、请求响应和日志作为附件。
我不会为了让报告好看而在每行代码上加 step,而是围绕业务动作组织,例如"创建交易申请""审批交易""校验风控结果",这样失败时更容易看出业务阶段。
3.15 如何处理用例之间的数据依赖? ★★★★★ 必问
考察点: 是否理解数据隔离的重要性及实现方式。
结构化回答话术:
优先通过 API、数据库或 fixture 为每条用例独立创建前置数据,并在结束后清理。必须传递的数据通过 fixture 返回值或明确的业务流程对象传递,不依赖全局变量和上一条用例执行结果。
如果一个场景天然包含多个连续步骤,应作为一条端到端业务用例;如果步骤需要分别验证,就提供可重复创建的前置状态,让每条用例也能独立运行。
四、框架设计与项目实战
4.1 你的 UI 自动化框架是如何设计的? ★★★★★ 必问
考察点: 是否真正做过框架,而不只是编写页面脚本。
结构化回答话术:
我的框架主要分为配置层、页面对象层、业务流程层、测试用例层、测试数据层、断言层和公共能力层。Playwright 负责浏览器操作,Pytest 负责 fixture、参数化和执行管理,Allure 展示报告,Jenkins 负责定时和按参数执行。
页面层只封装元素和单页面操作;业务层组合申请、审批、查询等流程;用例层描述测试场景和断言。环境地址、账号和超时放在配置中,账号密码通过环境变量注入。失败时自动保留截图、日志和 Trace。
在金融交易系统中,我把登录、交易申请、审批、风控校验和台账查询封装为公共能力,再通过 Excel 数据驱动覆盖现券、回购、基金和借贷等业务场景。
4.2 Page Object 模式是什么? ★★★★★ 必问
考察点: 是否理解 Page Object 的设计目标和维护价值。
结构化回答话术:
Page Object 是把页面元素定位和页面操作封装成对象,让测试用例通过业务含义调用页面能力,而不是直接操作定位器。这样页面变化时主要修改对应页面类,降低用例维护成本。
但 Page Object 不应该变成一个几千行的大类。我会按页面或稳定组件拆分,并把跨页面流程放到业务流程层,避免页面类同时承担数据、断言和流程控制。
4.3 页面对象层和业务流程层如何划分? ★★★★★ 必问
考察点: 是否具备合理的分层设计思维,避免页面类职责过重。
结构化回答话术:
页面对象层回答"这个页面如何操作",例如填写表单、点击提交和读取状态;业务流程层回答"一个业务如何完成",例如创建交易、完成审批和加入台账。
这样同一个页面方法可以被多个业务流程复用,流程变化时也不需要把复杂逻辑复制到每条测试用例中。断言仍然由用例层或独立验证层控制,避免页面方法内部偷偷决定测试通过。
4.4 自动化测试如何实现数据驱动? ★★★★★ 必问
考察点: 是否理解数据与逻辑分离的设计,能够处理数据校验和转换。
结构化回答话术:
数据驱动是把测试逻辑与场景数据分离,同一套流程通过不同输入、预期和配置覆盖多种业务。数据可以来自 YAML、JSON、Excel 或数据库,但进入用例前要转换成统一对象并校验 Schema。
我的项目中使用 Excel 维护场景类型、业务参数、配对 ID、指令索引和阶段预期值。框架读取后生成 Pytest 参数,金额比较采用明确的绝对和相对容差,日期、空值和枚举先标准化再断言。
4.5 UI 自动化应该断言什么? ★★★★★ 必问
考察点: 是否具备分层断言思维,能够平衡覆盖率与用例稳定性。
结构化回答话术:
断言应围绕业务结果,而不是只判断页面是否打开或按钮是否可见。通常包括页面提示、关键字段、业务状态、接口响应和数据库结果。不同层次的证据相互补充。
例如提交交易后,我不仅断言"提交成功"的提示,还会查询交易列表和数据库状态,验证金额、方向、产品、审批状态等关键字段。断言过少容易漏报,断言过多且与业务无关又会造成脆弱用例。
4.6 页面、接口和数据库结果不一致时如何定位? ★★★★★ 必问
考察点: 是否具备分层定位思路,能够沿数据链路逐层缩小问题范围。
结构化回答话术:
我会先固定测试数据和时间范围,确认三方比较的是同一业务主键;然后查看页面展示值、接口原始响应和数据库原始记录,排除格式、精度、枚举和时区差异。
如果数据库正确、接口错误,重点检查服务端查询、转换和缓存;接口正确、页面错误,重点检查前端字段映射、格式化和状态管理;数据库尚未更新,则检查异步任务、消息消费和事务。最终提供请求响应、SQL、截图和时间点作为证据,推动责任方修复并完成关联回归。
4.7 如何降低 UI 自动化用例的维护成本? ★★★★★ 必问
考察点: 是否具备从架构层面系统化降低维护成本的能力。
结构化回答话术:
核心措施包括稳定定位器、Page Object 分层、公共业务流程封装、统一等待、数据与代码分离、环境配置集中管理,以及失败证据自动收集。还要控制自动化范围,优先覆盖稳定、核心和高频回归场景。
我会定期统计失败原因,把产品缺陷、环境问题、测试数据问题和脚本问题分类。高频变化但低风险的页面不盲目追求 UI 全覆盖,可以下沉到接口层验证。
4.8 自动化用例偶发失败如何治理? ★★★★★ 必问
考察点: 是否具备系统化的稳定性治理方法论。
结构化回答话术:
先通过多次运行和失败产物确认规律,再按定位器、等待条件、测试数据、账号冲突、环境波动、接口性能和脚本逻辑分类。每类问题采用对应措施,而不是统一增加等待和重跑。
我会统计用例稳定率和失败原因,对不稳定用例设置治理期限。只有瞬时网络问题允许有限重试;定位器和业务等待问题必须从代码上修复。治理目标是让失败结果可信,而不只是让流水线变绿。
4.9 如何接入 Jenkins 持续集成? ★★★★★ 必问
考察点: 是否掌握 CI 集成的完整流程和环境管理。
结构化回答话术:
Jenkins 流程通常包括拉取代码、创建环境、安装依赖、注入环境和账号参数、执行 Pytest、收集 Allure 结果及归档截图和 Trace。可以支持手动触发、定时回归、按模块执行和不同环境参数化。
我的 Jenkins 主控运行在 Linux,UI 自动化根据浏览器和业务系统条件调度到 Windows 执行节点。构建失败后先判断代码拉取、依赖、环境连接、测试执行还是报告阶段失败,再通知相关人员,避免把所有流水线失败都当成产品缺陷。
4.10 如何介绍你做过的 Python + Playwright + Pytest 项目? ★★★★★ 必问
考察点: 是否有真实项目经验,能否结构化说明业务背景、技术方案、难点和个人贡献。
结构化回答话术:
我最近几年主要负责金融交易和风控系统的 UI 自动化工程化建设。项目覆盖交易申请、审批、风控校验和交易台账等核心流程,我从零搭建了 Python + Playwright + Pytest 自动化框架。
框架采用 Page Object 和业务流程分层,使用 fixture 管理浏览器、登录状态和测试数据,通过 Excel 参数化覆盖现券、回购、基金、债券借贷等不同业务场景。断言不仅验证页面结果,还会结合接口和数据库校验关键状态与金额。
我将项目接入 Jenkins,支持定时回归、模块化执行和环境参数化,并通过 Allure 展示执行结果。失败时自动保留截图、日志和 Trace,便于区分产品缺陷、环境问题和脚本问题。
项目中比较难的部分是复杂表格数据采集、异步业务状态等待以及脚本稳定性治理。例如交易台账使用 ag-grid 和横向虚拟滚动,我通过业务主键分段采集并合并数据,再与预期结果比较。整个项目的重点不是简单模拟点击,而是把核心业务回归做成可维护、可追踪的自动化体系。
可能追问:
- 这个框架中你亲自负责了哪些部分?
- 最难定位的一次失败是什么?
- 自动化覆盖率和稳定率如何统计?
- 为什么某些场景使用 UI,而不是接口自动化?
- 如果重新设计一次,你会优先优化什么?
高频代码题
1. Pytest 参数化示例
import pytest
@pytest.mark.parametrize(
"username,password,expected",
[
pytest.param("valid_user", "valid_password", "首页", id="登录成功"),
pytest.param("valid_user", "wrong_password", "用户名或密码错误", id="密码错误"),
],
)
def test_login(login_page, username, password, expected):
login_page.login(username, password)
assert login_page.get_result_text() == expected2. Playwright 页面对象示例
from playwright.sync_api import Page, expect
class LoginPage:
def __init__(self, page: Page):
self.page = page
self.username = page.get_by_label("用户名")
self.password = page.get_by_label("密码")
self.login_button = page.get_by_role("button", name="登录")
def open(self):
self.page.goto("/login")
def login(self, username: str, password: str):
self.username.fill(username)
self.password.fill(password)
self.login_button.click()
def assert_login_success(self):
expect(self.page.get_by_role("heading", name="首页")).to_be_visible()3. fixture 管理 Context 和 Page
import pytest
@pytest.fixture
def context(browser):
context = browser.new_context()
yield context
context.close()
@pytest.fixture
def page(context):
page = context.new_page()
yield page4. 等待接口响应
with page.expect_response(
lambda response: "/api/trade/submit" in response.url
and response.request.method == "POST"
) as response_info:
page.get_by_role("button", name="提交").click()
response = response_info.value
assert response.status == 200
body = response.json()
assert body["code"] == 0快速背诵模板
1. 回答技术题
我先说结论:……
实际测试时,我主要从 A、B、C 三个方面处理:……
例如在我的某项目中:……
最后我还会通过……形成闭环。
2. 回答项目题
项目背景是什么 → 我负责什么 → 使用什么方案 → 遇到什么难点 → 如何解决 → 取得什么效果。
3. 回答故障定位题
先稳定复现 → 排除环境、数据和脚本问题 → 按链路分层定位 → 提供日志与证据 → 推动修复 → 原场景复测并做关联回归。
4. 回答"如何保证"类问题
先明确标准和风险 → 制定测试策略 → 分层验证 → 保留日志和数据证据 → 通过持续回归保证长期有效。
面试前重点背诵清单
如果时间有限,优先掌握以下 15 题:
- 1.1 Python 为什么适合自动化测试?
- 1.10 Python 如何连接数据库并校验数据?
- 2.1 为什么选择 Playwright?
- 2.2 Browser、Context、Page 的关系。
- 2.3 自动等待机制。
- 2.5 稳定定位器设计。
- 2.10 登录状态复用。
- 2.12 接口响应监听。
- 2.13 动态表格和虚拟滚动。
- 3.2 fixture。
- 3.6 参数化。
- 3.10 并行执行。
- 3.13 失败截图和 Trace。
- 4.1 框架设计。
- 4.10 完整项目介绍。
回答时容易踩的坑
- 不要只背 API 名称,要说明在什么场景下使用以及为什么选择它。
- 不要把工具操作当成测试能力,重点要讲业务分层、用例设计和失败定位。
- 不要把所有问题都归给开发,先说明如何排除环境、数据和脚本问题。
- 不要夸大自动化覆盖率和收益,使用能够解释和追问的真实内容。
- 不要背成零散关键词,要用完整句子表达。
- 项目例子尽量包含具体对象,例如交易编号、债券代码、交易方向、台账查询。
- 回答框架设计时,要说清楚各层职责和为什么这么分,而不是简单列出目录名。
- 回答 Playwright 问题时必须提到自动等待、网络拦截和 Trace,这是它区别于 Selenium 的核心能力。
面试复习建议
第一轮:优先掌握五星题
要求能够脱离文档完整回答,并结合至少一个真实项目案例。
- Python 为什么适合自动化测试?
- 如何处理 Python 异常?
- Python 如何连接数据库并校验数据?
- 为什么选择 Playwright,而不是 Selenium?
- Playwright 的 Browser、Context 和 Page 是什么?
- Playwright 的自动等待机制是什么?
- Playwright 常用定位方式有哪些?
- 如何设计稳定的元素定位器?
- 为什么不建议大量使用 wait_for_timeout?
- 如何复用登录状态?
- 如何监听接口响应并做断言?
- 如何处理动态表格和虚拟滚动表格?
- 如何处理遮罩层、动画和偶发点击失败?
- Playwright 的 Trace 有什么作用?
- Pytest 相比 unittest 有什么优势?
- 什么是 fixture?
- conftest.py 有什么作用?
- 如何实现参数化测试?
- 如何实现并行执行?
- 如何在失败时自动截图并保存 Trace?
- 如何把 Pytest 与 Allure 结合?
- 如何处理用例之间的数据依赖?
- 你的 UI 自动化框架是如何设计的?
- Page Object 模式是什么?
- 页面对象层和业务流程层如何划分?
- 自动化测试如何实现数据驱动?
- UI 自动化应该断言什么?
- 页面、接口和数据库结果不一致时如何定位?
- 如何降低 UI 自动化用例的维护成本?
- 自动化用例偶发失败如何治理?
- 如何接入 Jenkins 持续集成?
- 如何介绍你做过的 Python + Playwright + Pytest 项目?
第二轮:掌握四星题
重点补充 Playwright 特殊交互处理、fixture 作用域、Pytest 钩子、重跑机制和数据驱动。
第三轮:理解三星题
确保追问时能够说清核心原理和基本做法,如 *args/**kwargs、生成器、类方法区别、skip/xfail 等。
第四轮:选学扩展题
根据目标岗位(UI 自动化 / 测试开发 / 自动化测试工程师)选择对应方向的深入题目进行准备。
本文正在根据真实项目经验整理,后续持续补充。