

在现代 Web 开发中,尤其是构建 AI Agent 类复杂应用时,端到端(E2E)浏览器测试越来越重要。它不仅能验证页面是否正确渲染,更能真实模拟用户交互、动态内容生成和 AI 响应流程。
Pest 测试框架结合 Playwright 浏览器自动化工具,为 PHP 开发者提供了一套简洁、高效且强大的解决方案。本文将全面介绍这一技术组合的原理、实战架构及最佳实践。
Pest 的 PHP 进程从不直接操作浏览器。所有的浏览器操作都通过 Playwright Server 中转
┌──────────────┐ TCP/WebSocket ┌──────────────────┐ CDP ┌───────────┐
│ Pest PHP │ ──────────────────→ │ Playwright Server │ ────────→ │ Chromium │
│ (测试进程) │ ←────────────────── │ (Node.js 进程) │ ←──────── │ (浏览器) │
└──────────────┘ JSON-RPC 响应 └──────────────────┘ └───────────┘
Pest 中的 Client.php 负责将 PHP 方法调用翻译成 Playwright 的协议消息,通过 WebSocket 发送给 Server,再将结果映射回 PHP 对象。这是一套完整的跨语言 RPC 机制。
Pest 是由 Nuno Maduro 创建的现代 PHP 测试框架。它构建在 PHPUnit 之上,但大幅提升了开发者体验,被誉为“PHP 中最快乐的测试框架”。Pest 采用 it()、describe() 等简洁语法,让测试代码像自然语言一样清晰易读,同时完全兼容 PHPUnit。
核心优势:
Playwright 是微软开发的开源浏览器自动化库,被业界公认为目前最先进的浏览器自动化工具之一。它支持 Chromium、Firefox 和 WebKit 三大浏览器内核,提供自动等待、截图、视频录制、网络拦截等强大功能。
Playwright 亮点:
通过官方 pest-plugin-browser 插件,Pest 可以直接在 PHP 代码中驱动 Playwright,让 PHP 开发者无需切换语言即可享受顶级浏览器自动化能力。
PHP 项目写浏览器测试,历来是一件令人头疼的事。传统方案如 Laravel Dusk 基于 ChromeDriver,Selenium 需要独立的 Java 服务进程,配置复杂度远超单元测试。更深层的问题有三个:
困境一:运行环境割裂。PHP 应用跑在容器里,浏览器引擎跑在宿主机上,两者之间的网络通信、进程管理、生命周期同步,每一环都可能出问题。
困境二:测试代码脆弱。一个按钮文本从 “提交” 变成 “提交→”,测试就红了;一个 DOM 层级调整,选择器就失效了。维护成本往往高于编写成本。
困境三:AI 时代的错位。当 AI Agent 可以在几秒内生成功能代码时,测试代码却依然需要人工逐行编写。代码产出速度和测试覆盖速度之间的鸿沟越来越大。
Pest 的 pest-plugin-browser 选择 Playwright 作为底层引擎,正是为了同时回应这三个困境。
文以一个实际项目为例:基于 webman 2.1 的 FFmpeg AI 聊天页面。该页面提供视频转码、合并、截图、音频提取、水印等多种 AI 驱动的功能,需要通过浏览器测试确保界面交互和 AI 响应流程可靠。 测试目标页面:http://127.0.0.1:8787/ffmpeg
本次测试架构
┌─────────────────────────────────────────┐
│ 宿主机 (Windows/glibc) │
│ ┌─────────────────────────────────┐ │
│ │ Playwright Server (:9999) │ │
│ │ 管理 Chromium 浏览器实例 │ │
│ └─────────────────────────────────┘ │
│ ▲ │
│ │ TCP (局域网 IP) │
│ ┌─────────────────┴───────────────┐ │
│ │ Docker 容器 (Alpine/musl) │ │
│ │ Pest PHP ──→ 192.168.0.108:9999│ │
│ │ webman (:8787) │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
宿主机 Playwright + 容器 Pest。
npx playwright run-server --host 0.0.0.0 --port 9999http://127.0.0.1:8787测试代码示例
<?php
declare(strict_types=1);
test('ffmpeg 页面可以正常访问', function () {
$this->visit('http://127.0.0.1:8787/ffmpeg')
->assertSee('FFmpeg Agent');
});
test('ffmpeg 页面包含正确的标题', function () {
$this->visit('http://127.0.0.1:8787/ffmpeg')
->assertTitle('FFmpeg Agent - 音视频处理 AI 助手');
});
test('ffmpeg 页面包含核心功能标签', function () {
$this->visit('http://127.0.0.1:8787/ffmpeg')
->assertSee('视频转码')
->assertSee('视频合并')
->assertSee('视频截图')
->assertSee('音频提取')
->assertSee('添加水印')
->assertSee('信息查询');
});
共编写 9 个核心测试用例,覆盖页面访问性、标题、功能标签、交互元素、输入行为、URL 路径等。全部测试通过,总耗时约 26 秒。
PASS Tests\Browser\FFmpegPageTest
✓ ffmpeg 页面可以正常访问 5.23s
✓ ffmpeg 页面包含正确的标题 1.99s
✓ ffmpeg 页面包含核心功能标签 2.15s
✓ ffmpeg 页面包含欢迎消息 2.12s
✓ ffmpeg 页面包含输入框和发送按钮 2.23s
✓ ffmpeg 页面包含快速示例按钮 2.07s
✓ 用户可以在输入框中输入消息 2.04s
✓ 页面 URL 路径正确 1.99s
✓ 页面 HTML 源码包含关键元素 2.11s
Tests: 9 passed (24 assertions)
Duration: 26.61s
Pest + Playwright 的组合,解决的不只是"PHP 怎么做浏览器测试"这个问题,而是在回答一个更根本的问题:在 AI Agent 时代,测试框架应该长什么样?三个关键答案:
这个原则在 AI Agent 时代变得更加重要。因为 AI Agent 需要灵活地组合工具——今天用 Pest + Playwright,明天可能用 MCP + Chromium,后天可能用视觉模型直接验证。只有当每个组件都可以独立替换时,AI Agent 才能真正成为测试的主人,而不是被工具链绑定的奴隶。
Pest 让 PHP 开发者能用优雅的方式写测试,Playwright 让测试能可靠地驱动浏览器,AI Agent 让测试能自动生成和自愈。三者合一,才是浏览器测试的未来。