保姆级教程:从零用Playwright+Pytest写一个带截图和Allure报告的百度搜索测试
零基础玩转Playwright+Pytest:手把手打造带截图的Allure测试报告
第一次接触UI自动化测试时,我盯着满屏的Selenium报错信息发呆。直到发现Playwright这个神器——它像一位耐心的老师,用清晰的错误提示和直观的API带我走出了新手村。今天,我们就用最接地气的方式,从百度搜索这个经典案例开始,体验现代测试工具链的丝滑流畅。
1. 环境准备:五分钟搞定测试装备
工欲善其事,必先利其器。打开终端,让我们用pip这条魔法咒语召唤测试界的四大护法:
pip install playwright pytest pyyaml allure-pytest python -m playwright install chromium小贴士:如果遇到网络问题,可以尝试添加--index-url https://pypi.tuna.tsinghua.edu.cn/simple使用国内镜像源
验证安装是否成功:
import playwright print(playwright.__version__) # 应该输出类似1.40.0的版本号注意:Allure需要额外安装命令行工具,推荐从 官方GitHub仓库 下载最新版本,解压后将bin目录加入系统PATH
2. 第一个测试脚本:让浏览器自动搜索
在项目根目录创建test_baidu.py,我们来编写一个会自己操作浏览器的"机器人":
import allure from playwright.sync_api import Page def test_baidu_search(page: Page): """测试百度搜索功能""" # 访问百度首页 page.goto("https://www.baidu.com") # 定位搜索框并输入关键词 search_box = page.locator("#kw") search_box.click() search_box.fill("Playwright自动化测试") # 点击搜索按钮 search_button = page.get_by_role("button", name="百度一下") search_button.click() # 验证搜索结果 assert "playwright.dev" in page.title() # 保存截图 page.screenshot(path="search_result.png") allure.attach.file("search_result.png", name="搜索结果", attachment_type=allure.attachment_type.PNG)运行测试的命令很简单:
pytest test_baidu.py --alluredir=./report allure serve ./report3. 进阶技巧:用YAML管理测试数据
当测试用例增多时,硬编码的数据会成为维护噩梦。我们用YAML来解耦:
创建data/search_keywords.yaml:
test_cases: - name: "搜索Python教程" url: "https://www.baidu.com" keyword: "Python入门教程" expected: "菜鸟教程" - name: "搜索自动化测试" url: "https://www.baidu.com" keyword: "UI自动化测试" expected: "Playwright"修改测试脚本读取YAML数据:
import yaml import pytest def load_test_data(): with open("data/search_keywords.yaml") as f: return yaml.safe_load(f) @pytest.mark.parametrize("case", load_test_data()["test_cases"]) def test_baidu_search(page: Page, case): page.goto(case["url"]) page.locator("#kw").fill(case["keyword"]) page.get_by_role("button", name="百度一下").click() assert case["expected"] in page.title()4. 打造专业测试报告:Allure的魔法
Allure能把枯燥的测试结果变成视觉盛宴。我们在conftest.py中添加这些钩子函数:
import allure import pytest from datetime import datetime @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): outcome = yield report = outcome.get_result() if report.when == 'call': # 添加环境信息 allure.dynamic.title(item.function.__doc__ or item.name) allure.dynamic.description( f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" f"运行时长: {round(report.duration, 3)}秒" ) # 自动附加页面截图 if "page" in item.funcargs: page = item.funcargs["page"] screenshot = page.screenshot() allure.attach(screenshot, name="页面截图", attachment_type=allure.attachment_type.PNG)这样生成的报告会包含:
- 美观的时间线图表
- 丰富的环境信息
- 自动截取的页面快照
- 清晰的测试步骤树
5. 常见问题排雷指南
在实际教学中,我发现新手常会遇到这些"坑":
浏览器无法启动?
- 确保执行过
playwright install chromium - 检查防火墙是否阻止了浏览器进程
- 尝试添加
--headed参数可视化运行
pytest --headed test_baidu.py元素定位失败?Playwright提供了多种定位策略:
| 定位方式 | 示例 | 适用场景 |
|---|---|---|
| CSS选择器 | page.locator("#kw") | 常规元素 |
| 文本定位 | page.get_by_text("登录") | 按钮/链接文本 |
| 角色定位 | page.get_by_role("button") | 标准HTML角色 |
| XPath | page.locator("//input[@name='wd']") | 复杂层级结构 |
测试不稳定?
- 添加等待策略代替硬性sleep:
page.locator("#kw").click(timeout=5000) # 显式等待5秒 page.wait_for_selector(".result", state="visible") # 等待结果出现 - 启用重试机制:
pytest --reruns 3 --reruns-delay 1 # 失败时自动重试3次
6. 项目结构最佳实践
成熟的测试项目应该像乐高积木一样模块化:
baidu_test/ ├── conftest.py # 共享fixture和钩子 ├── data/ │ └── search_keywords.yaml ├── pages/ # 页面对象模型 │ └── baidu_page.py ├── tests/ │ └── test_search.py ├── utils/ # 工具函数 │ ├── allure_util.py │ └── screenshot.py └── reports/ # 自动生成其中baidu_page.py封装页面操作:
class BaiduPage: def __init__(self, page): self.page = page self.search_box = page.locator("#kw") self.search_button = page.get_by_role("button", name="百度一下") def navigate(self): self.page.goto("https://www.baidu.com") def search(self, keyword): self.search_box.fill(keyword) self.search_button.click()这样测试用例就变得极其简洁:
def test_search(baidu_page): baidu_page.navigate() baidu_page.search("Playwright") assert "Playwright" in baidu_page.page.title()7. 调试技巧:让问题无所遁形
Playwright自带的调试工具是排查问题的利器:
录制功能:
playwright codegen https://www.baidu.com会启动一个浏览器窗口,你的所有操作都会自动生成对应的Python代码
追踪查看:
# 在测试开始时启动追踪 context = browser.new_context() context.tracing.start(screenshots=True, snapshots=True) # 测试结束后保存追踪文件 context.tracing.stop(path="trace.zip")用Playwright Inspector查看追踪文件:
playwright show-trace trace.zip这个可视化工具能让你:
- 逐帧回放测试过程
- 查看每个步骤的DOM快照
- 检查网络请求和响应
- 分析执行时间线
8. 持续集成:让测试自动运行
最后,我们让这套测试能在GitHub Actions上每天自动执行:
创建.github/workflows/test.yml:
name: UI Automation Test on: schedule: - cron: '0 0 * * *' # 每天UTC时间0点运行 push: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt python -m playwright install python -m playwright install-deps - name: Run tests run: | pytest --alluredir=./report - name: Upload Allure report uses: actions/upload-artifact@v3 with: name: allure-report path: ./report在本地开发时,我习惯用这个alias快速验证改动:
alias runtest='pytest -xvs && allure serve report'