一、写在前面
第二周已经熟练掌握接口自动化的完整流程,本周正式进入 Web UI 自动化测试 学习阶段。本次我选择主流新秀工具 Playwright 而非传统的 Selenium。
选择 Playwright 的原因非常明确:相比 Selenium,它运行速度更快、稳定性更高、报错信息更详细、API 更现代化;同时内置智能自动等待,不需要频繁写 sleep 强制等待,非常适合新手入门。
本周核心目标:从零搭建 Playwright 环境,掌握元素定位、页面操作、等待与断言,独立跑通 saucedemo 商城完整购物自动化流程,并结合 pytest 实现用例管理、参数化用例和 HTML 测试报告,完成一整套标准化 Web 自动化体系学习。
二、Day 1|Playwright 环境搭建与首个自动化脚本
本周第一天主要完成环境搭建,Playwright 安装简单、一键部署,仅需两条命令即可完成全部环境初始化:
pip install pytest-playwright
playwright install
环境部署完成后,我编写了人生第一个 Web 自动化脚本:自动打开百度网页、获取标题并全屏截图,成功实现代码操控浏览器。
from playwright.sync_api import sync_playwright
def test_open_baidu():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.baidu.com")
page.screenshot(path="baidu.png")
print("页面标题:", page.title())
browser.close()
运行命令:
pytest test_web_playwright.py -v
脚本运行成功,终端输出 1 passed,浏览器自动打开、截图、关闭,让我直观理解了 Web 自动化的核心逻辑:代码驱动浏览器完成人工操作。
下方为脚本运行成功的终端日志截图:
三、Day 2|元素定位:Web自动化核心基本功
Web 自动化的本质就是:精准找到元素,再模拟操作元素。Playwright 统一使用 page.locator() 完成定位,我系统掌握了四种最常用、最高频的定位方式:
| 定位方式 | 代码写法 | 使用场景 |
|---|---|---|
| ID定位 | page.locator("#user-name") | 唯一标识,优先级最高 |
| Class定位 | page.locator(".btn_inventory") | 批量元素、按钮列表 |
| 文本定位 | page.locator("text=Login") | 固定文字按钮、链接 |
| 属性定位 | page.locator("[data-test='username']") | 稳定性最强,企业项目首选 |
在定位过程中,我使用 F12 开发者工具查看 saucedemo 登录页面 DOM 结构,精准定位了用户名输入框、密码输入框、登录按钮。
运行命令:
python test_locator_practice.py
终端输出:
下图为浏览器开发者工具查看页面元素的截图:
四、Day 3|页面基础操作:模拟真实用户行为
掌握定位后,开始学习 Playwright 核心交互 API,全部语法简洁易懂、贴近人工操作:输入、点击、获取文本、截图等。
# 输入账号密码
page.locator("#user-name").fill("standard_user")
# 点击登录按钮
page.locator("#login-button").click()
# 获取商品文本信息
text = page.locator(".inventory_item_name").text_content()
# 页面截图保存
page.screenshot(path="page.png")
当天成功跑通基础链路:打开 saucedemo 登录页 → 输入正确账号密码 → 点击登录 → 成功跳转商品首页,完成 Web 自动化最基础的业务闭环。
五、Day 4|等待策略 + 业务断言,让脚本稳定可用
刚开始跑脚本时经常偶尔报错,核心原因是 页面异步加载未完成。虽然 Playwright 自带自动等待,但页面跳转后的关键元素仍需要手动精准等待,避免脚本执行过快导致元素找不到。
我重点掌握了 wait_for_selector 精准等待方式:只等待关键元素渲染完成,不浪费多余时间。
# 等待商品列表加载完成再执行下一步
page.wait_for_selector(".inventory_list")
同时加入断言机制,让脚本具备测试判断能力,不再只是“自动操作”,而是真正的“自动测试”。
# 断言页面标题正确
assert "Swag Labs" in page.title()
# 断言首页商品数量为6个
items = page.locator(".inventory_item")
assert items.count() == 6
运行命令:
pytest test_login_flow.py -v
加入等待和断言后,脚本运行非常稳定,每一步结果都可校验、可追溯,真正符合自动化测试规范。
下图是优化等待与断言后,登录流程全步骤执行通过的终端日志:
六、Day 5|完成 saucedemo 完整购物流程自动化
本周核心任务:实现商城端到端全流程自动化,覆盖用户真实购物全部场景,链路完整闭环:
登录页面 → 商品加购 → 进入购物车 → 点击结算 → 填写收货信息 → 提交订单 → 校验订单成功
我独立编写完成整套自动化脚本,全程无人工干预,自动跑通完整购物流程,最终成功生成订单完成页面截图,彻底实现从“简单操作”到“完整项目级自动化”的跨越。
运行命令:
python test_saucedemo_full_flow.py
下方是完整购物流程全步骤通过的终端打印日志:
order_complete.png 订单完成页面:
七、Day 6|接入 pytest 框架,生成 HTML 可视化报告
为了让自动化脚本更加标准化、工程化,我将原生 Playwright 脚本改造为 pytest 标准用例格式,并学会生成 HTML 可视化测试报告。
执行命令简单高效:
pytest test_login_flow.py -v
运行后自动生成网页版测试报告,可直观查看:用例执行状态、运行时长、成功失败详情,解决了纯终端日志不直观、无法留存的问题,符合企业自动化测试交付标准。
终端 1 passed 成功:
执行命令后自动生成标准化 HTML 测试报告,可在浏览器打开查看用例执行统计、运行耗时。
下图为生成后的 web_report.html 测试报告页面:
八、Day 7|高阶拓展:批量加购、金额断言、函数封装、参数化用例
8.1 多件商品加购 + 购物车数量校验
优化单商品加购逻辑,实现批量加购,并通过断言校验购物车商品数量准确:
add_buttons = page.locator(".btn_inventory")
for i in range(2):
add_buttons.nth(i).click()
cart_items = page.locator(".cart_item")
assert cart_items.count() == 2
8.2 正则提取订单总价,实现数值断言
利用正则表达式提取页面价格文本,清洗出纯数字,完成业务数据校验,避免价格展示异常:
import re
total_text = page.locator(".summary_total_label").text_content()
price_match = re.search(r'\$([\d.]+)', total_text)
if price_match:
total_price = float(price_match.group(1))
assert total_price > 0
print(f"✅ 总价校验通过:${total_price:.2f}")
8.3 函数封装,彻底优化代码结构
将登录、加购、结算、完成订单全部抽分为独立公共函数,主流程极简、清晰、高复用,完全贴近企业封装思想:
def test_saucedemo_optimized():
login(page)
expect_count = add_items_to_cart(page, count=2)
checkout(page, expect_goods_num=expect_count)
complete_order(page)
封装后代码可读性极强、方便迭代、方便维护,彻底告别杂乱堆砌式代码。
8.4 pytest参数化,批量覆盖多账号登录场景
使用参数化技术,一套代码覆盖正常账号、锁定账号、异常账号三种核心场景,自动区分预期成功和预期失败,大幅提升用例覆盖率。
@pytest.mark.parametrize("username, password, expected", [
("standard_user", "secret_sauce", True),
("locked_out_user", "secret_sauce", False),
("problem_user", "secret_sauce", True),
])
def test_login_with_param(username, password, expected):
# 自动执行多组登录用例并断言
运行命令:
pytest test_login_parametrize.py -v
终端输出:
最终三条用例全部执行通过,终端显示 3 passed,批量测试效果高效稳定。
九、本周收获、问题复盘与学习感悟
9.1 本周掌握技能清单
✅ 熟练搭建 Playwright 自动化环境、安装浏览器驱动
✅ 精通四大主流元素定位方式,能够自主分析页面元素
✅ 熟练模拟用户点击、输入、截图、读取文本等操作
✅ 掌握页面等待策略,解决元素加载超时问题
✅ 熟练使用断言,完成页面元素、数量、数据校验
✅ 独立完成商城完整端到端 Web 自动化流程
✅ 熟练使用 pytest 管理用例、生成 HTML 测试报告
✅ 掌握代码封装思想,写出高复用、简洁规范脚本
✅ 掌握正则提取页面数值,实现业务数据断言
✅ 掌握 pytest 参数化,实现多场景批量自动化测试
9.2 本周踩坑总结与解决方案
坑 1:页面 goto 访问超时、元素定位失败****
问题 : saucedemo 为境外站点,国内网络访问延迟高,页面异步资源加载不稳定;Playwright 默认 30 秒等待时长不足,跳转页面时常出现 DOM 未渲染完成,触发Page.goto Timeout,脚本偶尔定位元素失败。
解决方案 :****
1. 全局超时扩容:将全局默认等待时长调整至 90 秒 page.set_default_timeout(90000),给网络充足容错空间;
2. 页面跳转单独加超时:page.goto(url, wait_until="domcontentloaded", timeout=90000),使用domcontentloaded策略仅等待 DOM 骨架加载完成,不用等待全部图片、字体资源;
3. 拦截非必要静态资源:新增page.route拦截字体、图片、CSS 文件,减少外网请求数量,从根源缩短整页首次加载耗时;
4. 页面跳转后使用wait_for_selector精准等待核心业务元素,不依赖整页加载完成。
坑 2:订单页面截图字体加载超时****
问题 : 执行page.screenshot()捕获订单完成页面时,工具默认等待全部字体资源加载完毕,境外字体文件加载缓慢,触发截图 60 秒超时报错。
解决方案 :****
1. 页面初始化阶段拦截 woff/ttf 等字体文件,页面不再发起字体请求,规避截图时强制等待字体的逻辑;
2. 截图操作单独配置timeout=90000兜底延长等待时长,保证截图流程稳定。
坑 3:Playwright 版本参数不兼容报错****
问题 : ****该版本 Playwright 不存在fonts_wait截图参数,添加该参数后直接抛出TypeError,完整购物流程执行到最后截图步骤中断。
解决方案 :****
1. 查阅对应版本官方 API 文档,删除不存在的不兼容参数;
2. 改用拦截字体资源的方案替代fonts_wait参数,适配当前本地库版本。
9.3 本周学习感悟
这周最大的感受是:接口自动化和 Web 自动化底层思维完全相通,都是「定位资源—模拟操作—结果断言」。只是接口调用的是接口地址,Web 操作的是页面元素。有第二周 Python 和 pytest 基础,本周上手非常顺滑。
Playwright 确实是新手最友好的自动化工具,自动等待、报错清晰、API简单统一,极大降低了 Web 自动化的入门门槛。
同时我也深刻意识到:自动化测试大部分报错不是技术难,而是拼写、细节、等待时机、元素定位稳定性问题。只要愿意认真读报错信息,80% 的问题都可以快速解决,不需要盲目猜测。
十、补充:PO模式重构与Allure报告接入
-
PO模式重构:把代码从函数式改为Page Object Model,每个页面单独封装成一个类,主流程从50行精简到10行左右,代码结构更清晰、可维护性更强。
-
Allure报告接入:用Allure替代pytest-html,生成更专业的测试报告。报告支持Feature/Story分类、Environment环境信息展示、关键步骤自动截图。
Allure报告截图
概览页:1个测试用例,100%通过。
Environment:展示了浏览器、Python版本、操作系统等测试环境信息。
Behaviors:按 Feature/Story 分类展示测试用例。
Suites:展示测试代码的目录层级结构
用例详情:展示测试用例的完整执行链路,包含每个步骤的页面截图。
这部分优化让我对自动化测试的工程化有了更深的理解,后续学习会继续朝这个方向推进。
十一、下周学习计划
1、深入学习 Playwright 高阶功能:网络拦截、元素拖拽、弹窗处理、录屏、多浏览器兼容测试;
2、学习 CI 持续集成,将自动化脚本接入 GitHub Actions,实现定时自动构建执行;
3、逐步入门性能测试,拓展测试技术栈广度。