Skip to main content

从 Testing Library 迁移

迁移原则

本指南描述了从 DOM Testing LibraryReact Testing LibraryVue Testing LibrarySvelte Testing Library 迁移到 Playwright 的实验性组件测试

note

如果您在浏览器中使用 DOM Testing Library(例如,您使用 webpack 打包端到端测试),您可以直接切换到 Playwright Test。以下示例专注于组件测试,但对于端到端测试,您只需将 await mount 替换为 await page.goto('http://localhost:3000/') 以打开被测页面。

速查表

Testing LibraryPlaywright
screenpagecomponent
querieslocators
async helpersassertions
user eventsactions
await 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.getByLabel('Password'), 'secret')await component.getByLabel('Password').fill('secret')
expect(screen.getByLabel('Password')).toHaveValue('secret')await expect(component.getByLabel('Password')).toHaveValue('secret')
screen.findByText('...')component.getByText('...')
screen.getByTestId('...')component.getByTestId('...')
screen.queryByPlaceholderText('...')component.getByPlaceholder('...')
screen.getByRole('button', { pressed: true })component.getByRole('button', { pressed: true })

示例

Testing Library:

import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('should sign in', async () => {
// 设置页面。
const user = userEvent.setup();
render(<SignInPage />);

// 执行操作。
await user.type(screen.getByLabel('Username'), 'John');
await user.type(screen.getByLabel('Password'), 'secret');
await user.click(screen.getByText('Sign in'));

// 通过等待 "Welcome" 消息出现来验证登录状态。
await screen.findByText('Welcome, John');
});

逐行迁移到 Playwright Test:

const { test, expect } = require('@playwright/experimental-ct-react'); // 1

test('should sign in', async ({ page, mount }) => { // 2
// 设置页面。
const component = await mount(<SignInPage />); // 3

// 执行操作。
await component.getByText('Username').fill('John'); // 4
await component.getByText('Password').fill('secret');
await component.getByText('Sign in').click();

// 通过等待 "Welcome" 消息出现来验证登录状态。
await expect(component.getByText('Welcome, John')).toBeVisible(); // 5
});

迁移要点(请参阅 Playwright Test 代码片段中的内联注释):

  1. 对于组件测试,从 @playwright/experimental-ct-react(或 -vue、-svelte)导入所有内容,或对于端到端测试,从 @playwright/test 导入。
  2. 测试函数被赋予一个与其他测试隔离的 page,以及一个在此页面中渲染组件的 mount。这是 Playwright Test 中两个有用的 fixtures
  3. 用返回组件定位器mount 替换 render
  4. 使用 locator.locator(selector[, options])page.locator(selector[, options]) 创建的定位器来执行大多数操作。
  5. 使用断言来验证状态。

迁移查询

所有查询,如 getBy...findBy...queryBy... 及其多元素对应项,都被替换为 component.getBy... 定位器。定位器在需要时始终自动等待和重试,因此您不必担心选择正确的方法。当您想要执行列表操作时,例如断言文本列表,Playwright 会自动执行多元素操作。

替换 waitFor

Playwright 包含自动等待条件的断言,因此您通常不需要显式的 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);

替换 within

您可以使用 locator.locator(selector[, options]) 方法在另一个定位器内创建定位器。

// Testing Library
const messages = document.getElementById('messages')
const helloMessage = within(messages).getByText('hello')

// Playwright
const messages = component.locator('id=messages')
const helloMessage = messages.getByText('hello')

Playwright Test 超能力

一旦您使用 Playwright Test,您将获得很多好处!

  • 完全零配置的 TypeScript 支持
  • 所有 Web 引擎(Chrome、Firefox、Safari)上跨任何流行的操作系统(Windows、macOS、Ubuntu)运行测试
  • 完全支持多个源、(i)frames标签页和上下文
  • 在多个浏览器中并行隔离运行测试
  • 内置测试工件收集:视频录制截图playwright traces

您还可以获得所有这些 ✨ 很棒的工具 ✨,它们与 Playwright Test 捆绑在一起:

延伸阅读

了解更多关于 Playwright Test 运行器的信息: