AI 自动探索网站并生成对应测试脚本,无需手工编写。大幅降低测试编写成本,提升覆盖率。
如果你的测试能够自己写——只需像真实用户一样使用你的应用呢?
在这篇文章中,我们探讨 Playwright MCP(模型上下文协议)在 Agent 模式下如何能自主导航你的应用、发现关键功能并生成可运行的测试——无需手动编写脚本。
我们将通过一个针对电影应用生成并运行测试的实时演示,展示 MCP 如何发现边界情况、构建测试覆盖,甚至发现你可能遗漏的 bug。
对于这个演示,我在 .vscode 项目文件夹内的 mcp.json 文件中本地运行 MCP Playwright 服务器。
{
"servers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
我准备了一个简单的测试提示词,位于 .github 文件夹中,命名为 generate_tests.prompt.md:
---
tools: ['playwright']
mode: 'agent'
---
- You are a playwright test generator.
- You are given a scenario and you need to generate a playwright test for it.
- DO NOT generate test code based on the scenario alone.
- DO run steps one by one using the tools provided by the Playwright MCP.
- When asked to explore a website:
1. Navigate to the specified URL
2. Explore 1 key functionality of the site and when finished close the browser.
3. Implement a Playwright TypeScript test that uses @playwright/test based on message history using Playwright's best practices including role based locators, auto retrying assertions and with no added timeouts unless necessary as Playwright has built in retries and autowaiting if the correct locators and assertions are used.
- Save generated test file in the tests directory
- Execute the test file and iterate until the test passes
- Include appropriate assertions to verify the expected behavior
- Structure tests properly with descriptive test titles and comments
然后在 VS Code 中我使用 Agent 模式,确保我的提示词已添加到上下文中,然后我只需输入:
Explore https://debs-obrien.github.io/playwright-movies-app
Agent 模式使用 Playwright MCP 导航到网站,并像真实用户一样使用浏览器探索应用。
让 agent 自由导航、发现功能,并根据其交互自动生成测试。
一旦 agent 开始探索,它尝试的第一件事是搜索功能。它在搜索栏中输入"Star Wars"——立即,我们发现了一个 bug。
搜索结果显示"Star Wars",但返回的电影标题是"Kill"。这显然是错的。
这是我在手动测试中没有注意到的边界情况。我之前搜索过 Garfield、Deadpool 和 Avengers 等术语——一切都运行正常。但现在,得益于 agent 的自主行为,我发现了一个回归。
✅ 结果:agent 发现了搜索问题——我完全遗漏的东西。
接下来,agent 切换应用的主题开关——在深色和浅色模式之间切换。它验证切换是否有效,点击导航链接,并继续探索。
在完成交互后,agent 总结了它的发现:
从该列表中,它选择搜索功能作为将要生成的测试的焦点。
你可以告诉 agent 你想要多少个测试。在这个案例中,我为演示请求了一个。
agent 基于交互生成完整的 Playwright 测试文件。它甚至在运行测试之前自动修复了 lint 错误。
以下是它生成的测试:
import { test, expect } from '@playwright/test';
test.describe('Movie search', () => {
test('Search for a movie by title', async ({ page }) => {
// Navigate to the movies app
await page.goto('https://debs-obrien.github.io/playwright-movies-app');
// Click on the search button to activate the search input
await page.getByRole('search').click();
// Type 'Star Wars' into the search input and press Enter
const searchTerm = 'Star Wars';
await page.getByRole('textbox', { name: 'Search Input' }).fill(searchTerm);
await page.getByRole('textbox', { name: 'Search Input' }).press('Enter');
// Verify we're on the search results page with correct title
await expect(page).toHaveTitle(`${searchTerm} - Search Results`);
// Verify the search results heading contains the search term
await expect(page.getByRole('heading', { level: 1 })).toHaveText(searchTerm);
await expect(page.getByRole('heading', { name: 'search results', level: 2 })).toBeVisible();
// Verify that search results are displayed
await expect(page.getByRole('list', { name: 'movies' })).toBeVisible();
// Click on a movie from search results
const firstMovie = page.getByRole('list', { name: 'movies' }).getByRole('link').first();
const movieTitleElement = firstMovie.getByRole('heading', { level: 2 });
const movieTitle = await movieTitleElement.textContent() || '';
await firstMovie.click();
// Verify that the movie details page is loaded with the correct title
await expect(page.getByRole('heading', { level: 1 })).toHaveText(movieTitle);
// Verify movie details sections are present
await expect(page.getByText('The Synopsis')).toBeVisible();
await expect(page.getByText('The Cast')).toBeVisible();
// Verify recommended movies section is present
await expect(page.getByRole('heading', { name: 'Recommended Movies' })).toBeVisible();
// Go back to search results
await page.getByRole('button', { name: 'Back' }).click();
// Verify we're back on the search results page
await expect(page.getByRole('heading', { level: 1 })).toHaveText(searchTerm);
});
});
生成后,它打开终端并运行测试。测试通过 ✅。
然后我们在 VS Code 中打开 Trace Viewer 来直观检查执行的步骤:
它搜索了 Star Wars。
点击了像 Deadpool 这样的结果。
验证了电影详情页面上的标题。
这是一个完整的循环:探索 → 生成 → 执行 → 审查。
这看起来可能像魔术——但这是一个真实的 AI 辅助开发示例。
以下是这种方法的强大之处:
你可以迭代、完善提示词、增加测试数量,或告诉 agent 探索不同的区域。这就像与一个永远不会疲倦的 AI 驱动的测试人员配对。
如果你正在构建现代应用,想要更好的测试覆盖而不需要手动编写所有内容,这是你尝试 Playwright MCP 的信号。
只需指向你的应用、给它一个提示词,让它探索。你会对它发现的内容感到惊讶——以及你能多快地从零测试到真实覆盖。测试不同的模型,看看什么最适合你。对于这个演示,我使用了 Claude Sonnet 3.7。
查看视频演示:
🧪 祝测试愉快——让机器人为你编写测试。在评论中告诉我你的想法,以及你是否在你的网站上尝试过并取得了一些成功。根据模型和版本等,它的行为方式可能会有所不同。
提示:在我 .vscode 文件夹中的 settings.json 文件中,我添加了这行代码,这样我就不必每次都点击继续。这对演示非常有用。
{
"chat.tools.autoApprove": true
}
某些评论可能仅对已登录的访问者可见。登录以查看所有评论。
对于进一步的操作,你可以考虑屏蔽此人和/或报告滥用。