ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Playwright 组件测试迁移指南:从 Testing Library 切换到 mount 组件测试模型

Playwright 组件测试迁移指南:从 Testing Library 切换到 mount 组件测试模型 Playwright 组件测试迁移指南从 Testing Library 切换到 mount 组件测试模型【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright本文基于 Playwright 官方文档 Migrating from Testing Library讲解如何将基于 DOM Testing Library、React Testing Library 或 Vue Testing Library 编写的组件测试迁移到 Playwright Test 内置的组件测试模型story gallery mountfixture。读完本文你将掌握完整的 API 对照表、逐行迁移方法并能结合源码理解mount()在底层是如何通过一个#rootLocator 驱动真实浏览器渲染的。一、迁移的总体思路原 Testing Library 的写法是在测试里直接调用render()内联地把组件挂载到测试环境Playwright 则把这份设置抽离到一个story一个把组件嵌入特定场景的小包装器由你自己的 dev server 以gallery组件库页面的形式对外提供测试中只用 id 引用它。gallery 的完整搭建方法见 组件测试指南。需要注意的一个边界情况如果你是在浏览器中使用 DOM Testing Library例如用 webpack 打包端到端测试可以直接切换到 Playwright Test——原文档中的示例聚焦组件测试但做端到端测试时只需把await mount(...)换成await page.goto(http://localhost:3000/)打开被测页面即可。二、API 对照速查表Cheat Sheet下面是原文档给出的完整对照表迁移时可直接照此替换Testing LibraryPlaywrightscreenpage与componentLocatorqueriesgetBy.../findBy...locatorsasync helperswaitFor等assertionsuser eventstesting-library/user-eventLocator 的 actionsawait user.click(screen.getByText(Click me))await component.getByText(Click me).click()await user.click(await screen.findByText(Click me))await component.getByText(Click me).click()await user.type(screen.getByLabelText(Password), secret)await component.getByLabel(Password).fill(secret)expect(screen.getByLabelText(Password)).toHaveValue(secret)await expect(component.getByLabel(Password)).toHaveValue(secret)screen.getByRole(button, { pressed: true })component.getByRole(button, { pressed: true })screen.getByLabelText(...)component.getByLabel(...)screen.queryByPlaceholderText(...)component.getByPlaceholder(...)screen.findByText(...)component.getByText(...)screen.getByTestId(...)component.getByTestId(...)render(Component /);一个 story 导出 await mount(Component/Default);const { unmount } render(Component /);const component await mount(...); await component.unmount();const { rerender } render(Component /);const component await mount(...); await component.update(props);三、完整示例逐行迁移一个登录测试Testing Library 原版import React from react; import { render, screen } from testing-library/react; import userEvent from testing-library/user-event; test(sign in, async () { // Setup the page. const user userEvent.setup(); render(SignInPage /); // Perform actions. await user.type(screen.getByLabelText(Username), John); await user.type(screen.getByLabelText(Password), secret); await user.click(screen.getByRole(button, { name: Sign in })); // Verify signed in state by waiting until Welcome message appears. expect(await screen.findByText(Welcome, John)).toBeInTheDocument(); });逐行迁移后场景先从测试搬进组件旁边的 story 文件import { SignInPage } from ./SignInPage; export const Default () SignInPage /; // 1然后测试按 id 挂载这个 storyconst { test, expect } require(playwright/test); // 2 test(sign in, async ({ mount }) { // 3 // Setup the page. const component await mount(pages/SignInPage/Default); // 4 // Perform actions. await component.getByLabel(Username).fill(John); // 5 await component.getByLabel(Password).fill(secret); await component.getByRole(button, { name: Sign in }).click(); // Verify signed in state by waiting until Welcome message appears. await expect(component.getByText(Welcome, John)).toBeVisible(); // 6 });迁移要点对应代码中的内联注释注释 1过去render()在测试里内联设置的一切——props、providers、mock 数据——都变成 story 的导出。story 运行在浏览器里因此活的 JS 对象回调、实例不再需要跨越 Node.js/浏览器边界进入测试。注释 2组件测试和端到端测试都统一从playwright/test导入。注释 3测试函数拿到page与其他测试隔离和mount在该 page 中渲染 story两个 fixtures。它们是 Playwright Test fixtures 体系的一部分。注释 4render被mountfixture 替代它接收 story id返回一个作用域限定在 gallery 根元素上的 component locator。注释 5用Locator.locator/Page.locator创建的 Locator 完成绝大多数交互操作。注释 6用 assertions 验证状态。四、查询Queries如何迁移Testing Library 的getBy...、findBy...、queryBy...及其多元素版本getAllBy...统一替换为component.getBy...Locator。由于 Locator始终自动等待并在必要时重试你不必再纠结该选getBy、findBy还是queryBy哪个方法——findByText的等待出现语义已由自动等待覆盖。当你需要做列表操作例如断言一列文本Playwright 会自动执行多元素操作详见 Locators 的 Lists 章节。五、用断言替换waitForPlaywright 的断言会自动等待条件成立因此通常不需要显式的waitFor/waitForElementToBeRemoved调用// Testing Library await waitFor(() { expect(getByText(the lion king)).toBeInTheDocument(); }); await waitForElementToBeRemoved(() queryByText(the mummy)); // Playwright await expect(page.getByText(the lion king)).toBeVisible(); await expect(page.getByText(the mummy)).toBeHidden();如果找不到合适的断言使用expect.poll替代await expect.poll(async () { const response await page.request.get(https://api.example.com); return response.status(); }).toBe(200);六、用嵌套 Locator 替换within可以用Locator.locator方法在一个 Locator 内部再创建 Locator作用即等价于within// Testing Library const messages screen.getByTestId(messages); const helloMessage within(messages).getByText(hello); // Playwright const messages component.getByTestId(messages); const helloMessage messages.getByText(hello);七、源码视角mountfixture 到底做了什么原文档强调mount接收 story id 并返回作用域限定在 gallery 根上的 component locator。这一点可以在仓库源码中得到印证mountfixture 的完整实现位于 packages/playwright/src/index.ts。从源码结构看其行为可以拆解为四步强制要求baseURL若配置中没有设置baseURLmount()会直接抛出mount() requires baseURL to point at the component gallery. Set it in your Playwright config.——这解释了为什么组件测试项目的配置里baseURL必须指向 gallery 页面见 组件测试指南的配置示例。导航到 galleryawait page.goto(baseURL)然后page.evaluate调用页面暴露的window.mount({ story: storyId, props })如果 gallery 页面没有定义window.mount()也会抛出明确的错误。返回作用域 Locatormount返回的是page.locator(#root)上附加了额外方法的对象——这就是component locator 限定在 gallery 根的实现本体测试中的所有查询都从#root向下作用域。附加update与unmountupdate(newProps)再次以新 props 调用window.mount不重新导航从源码注释看若 gallery 复用了渲染根节点框架会做 reconcile组件状态得以保留——这正是对照表中rerender的替代方案。unmount()则调用window.unmount?.()。此外源码中还有一个值得注意的细节调用window.mount时使用了{ exposeFunctions: true }选项意味着传入的 props 中如果包含函数会被转换为真正可在浏览器内调用、并回调到测试进程的函数。配套的 gallery 规范window.mount/window.unmount契约、#root挂载点、根节点复用等在仓库中以 agent skill 的形式提供位于 playwright-component-testing skill其中还附有 React 实现参考、Vue 实现参考 和 实验包迁移参考。八、迁移后你获得的 Playwright Test 能力一旦迁移到 Playwright Test你将获得原文档Playwright Test Super Powers完整的零配置 TypeScript 支持在所有主流浏览器引擎Chrome、Firefox、Safari与所有主流操作系统Windows、macOS、Ubuntu上运行测试对多源multi-origin、(i)frames、tabs 和 contexts 的完整支持参见 pages在多个浏览器中并行、隔离地运行测试内置测试产物截图、视频、trace收集见 recording options以及随 Playwright Test 捆绑的工具链Visual Studio Code 集成UI Mode带 watch mode 和时间旅行调试体验Playwright Inspector测试代码生成Playwright Tracing用于事后调试九、延伸阅读围绕 Playwright Test 运行器与组件测试的更多文档Getting StartedComponent testinggallery 搭建、story 约定、page.route拦截网络等完整模式LocatorsAssertionsAuto-waiting【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进