开始使用Playwright组件测试的详细教程

2,516 阅读11分钟

随着React和Vue等网络框架和库的广泛采用,网络应用的开发已经从每个页面只有一个HTML文件转变为拥有小型可重复使用的组件来渲染应用的特定部分。

同样,测试实践也从只有页面的端到端(E2E)测试扩展到有几个单元测试,同时单独测试前端组件。

如果你一直使用Playwright为你的应用程序实现E2E测试,你可能知道Playwright现在提供了单独测试前端组件的能力。

本教程将指导你使用Playwright最近发布的实验性组件测试功能,为你的Svelte、Vue和React组件编写单元测试的过程。

如果你想直接进入完成的测试案例,代码可在GitHub上的playwright-ct 分支的 [playwright-frontend-e2e-tests](https://github.com/vickywane/playwright-frontend-e2e-tests) 仓库中。

前提条件

本教程包含实践步骤,将指导你完成使用Playwright测试用React、Vue和Svelte构建的组件。你将在一个Yarn工作区克隆一个包含React、Vue和Svelte组件的模板项目。

要跟上这些步骤,你将需要以下东西:

  • 在你的电脑上安装Node.js v16
  • 在你的电脑上安装Git CLI
  • 对React、Vue或Svelte框架的基本熟悉程度

什么是 Playwright?

Playwright是一个开源的测试工具,主要支持网络应用,并对移动应用提供额外的实验性支持。

Playwright为你提供了使用JavaScript或TypeScript、Java、.NET和Python编写的可执行脚本自动测试的能力,而不是手动测试你的应用程序的界面。

Playwright的组件测试功能介绍

实验性的Playwright Test组件测试功能允许你创建测试案例,在其中导入和测试你的前端组件,而不是以编程方式导航到整个页面。

以前,已经使用Playwright进行E2E测试的开发者可能仍然需要单元测试。这些开发者不得不采用其他测试库,如Jest来直接测试他们的组件。

Playwright在2022年5月发布v1.22.0版本后,取消了这个限制,增加了组件测试功能。

目前,组件测试功能只支持React、Vue和Svelte。Playwright提供了一个额外的包,包裹了 [@playwright/test](https://www.npmjs.com/package/@playwright/test)包,以提供其他方法,如mount ,用于安装单个组件。

当你考虑使用Playwright进行前端单元测试时,请记住,组件测试功能仍处于实验阶段。因此,未来可能会对API进行修改。

使用Playwright测试你的组件

为了让你专注于使用Playright,本教程使用一个现有的monorepo项目,其中包含较小的React、Vue和Svelte应用程序。

monorepo使用Yarn工作区进行管理,React、Vue和Svelte应用程序将渲染同一个页面,显示从Rick and Morty API获取的JSON数据,其中有电视节目Rick and Morty的信息。

要开始工作,启动你的终端,使用Git CLI从GitHub仓库克隆预建的前端项目:

>git clone https://github.com/vickywane/playwright-frontend-e2e-tests.git

使用下面的命令,将目录改为克隆的项目,安装项目的依赖关系,并运行前端应用程序。该项目使用 [concurrently](https://www.npmjs.com/package/concurrently) 包下,从一个终端运行React、Vue和Svelte应用程序:

# change directory
cd playwright-frontend-e2e-tests

# install dependencies
yarn install 

# start all applications
yarn start:all

然后你应该看到类似下面的东西:

Playwright Component Testing Project Setup In Yarn Workspaces

通过为monorepo使用Yarn工作空间,你只需要在根目录下安装一次项目依赖,Yarn会自动将它们链接到其他项目。了解更多关于Yarn工作空间和monorepos的信息。

该项目中的每个前端应用程序显示从Rick and Morty API中获取的20个字符,这些字符跨越主组件中导入的三个子组件。在接下来的章节中,你将为每个子组件编写组件测试。

设置好项目后,让我们通过使用Playwright在单个应用程序中设置和编写E2E测试的过程。

为React组件设置Playwright组件测试

在开始编写E2E测试之前,使用你的浏览器导航到 http://localhost:3000,查看React应用程序。你将为下面图片中突出显示的SearchField 组件编写组件测试。

Playwright Component Testing Project Frontend, A Character Glossary For The Show Rick And Morty, With A Red Box Showing React SearchField Component Under A Title Component And Above Character Tiles

执行下一个命令,将你的终端目录改为react-components 文件夹,并启动交互式 Playwright CLI:

cd react-components

yarn create playwright --ct

上述命令中附加的--ct 标志将引导Playwright CLI设置测试,特别是测试组件。

在设置过程中,选择JavaScript 作为编写E2E测试的编程语言,并选择React 作为前端框架选项。

所有由 Playwright 生成的配置将被存储在playwright-ct.config.js 文件中,如果你想改变默认配置,可以调整该文件:

Contents Of Playwright Config File Set Up For Playwright Component Testing For React Components

作为设置过程的一部分,Playwright将自动安装@playwright/experimental-ct-react 包,以使用组件测试功能。

至此,Playwright已经在react-components 应用程序中设置好了。

使用你的代码编辑器打开整个playwright-frontend-e2e-tests 项目,因为你将在下一节开始创建你的第一个测试案例。

为React编写Playwright组件测试

使用你的代码编辑器,在react-components/src 目录中创建一个名为tests 的目录。tests 文件夹将包含你将为 Playwright 创建的所有测试文件。

接下来,在测试目录下创建一个SearchField.spec.jsx 文件。该文件将包含SearchField 组件的测试,这些测试是用来搜索一个字符的。

Playwright将文件名扩展名前缀为.spec 的文件识别为测试文件。

将下面的代码块内容添加到SearchField.spec.jsx 文件中,以断言SearchField 组件中的输入字段可以接受文本值。

下面的测试案例使用 [locator](https://playwright.dev/docs/api/class-locator) 方法找到具有search-field id属性的HTML元素,用文本Rick ,并断言输入元素的值是 "Rick":

import { test, expect } from '@playwright/experimental-ct-react';
import App, { SearchField } from '../App';

test('SearchField accepts text input', async ({ mount }) => {
    const searchComponent = await mount(<SearchField /> );
    const searchField = searchComponent.locator('#search-field')
    
    await searchField.fill('Rick')

    await expect(searchField).toHaveValue('Rick')
});

接下来,将下面的代码添加到SearchField.spec.jsx 文件中,以断言当组件中的按钮被点击时,executeSearch 道具被执行:

test('Click on `Find Character` button executes executeSearch prop', async ({ mount }) => {
    let isCalled = false
    const searchComponent = await mount(
        <SearchField
            executeSearch={() => isCalled = true}
        />
    );

    await searchComponent.locator('#search-field').fill('test character')
    await searchComponent.locator('#find').click()

    expect(isCalled).toBeTruthy()
});

作为良好用户体验的一部分,表单中的按钮应该被禁用,直到表单中的强制输入字段被填满。

添加下面的代码,断言当输入字段为空时,该组件的按钮被禁用:

test('Input field text length controls `Find Character` button disabled state', async ({ mount }) => {
    const searchComponent = await mount( <SearchField /> );

    const btn = await searchComponent.locator('#find').isDisabled()
    expect(btn).toBeTruthy()

    await searchComponent.locator('#search-field').fill('test character')
      await expect(searchComponent.locator('#find')).toBeEnabled();
});

这个测试案例是必要的,以确保只有在用户输入文本时才会触发搜索。

随着上述代码的添加,你现在在SearchField.spec.jsx 文件中有三个测试用例。让我们继续执行它们!

使用下面的命令执行你为SearchField 组件创建的测试用例:

yarn test-ct

你应该看到如下图所示的东西:

Result Of Executing Playwright Component Testing For React Components Showing Nine Passed Test Result And Instructions To Open Html Report

默认情况下,组件测试将在无头模式下执行,无需打开Chromium、Webkit和Firefox浏览器。在yarn test-ct 命令中添加--headless 标志,以启动这三个浏览器并查看正在测试的组件。

Playwright有一个内置功能,为每次测试运行生成并提供一个HTML报告。该HTML报告包含测试名称,执行状态,和每个测试案例的持续时间。

使用Playwright的show-report 命令为你的测试生成一个HTML报告:

npx playwright show-report

Playwright将在端口9323 ,为HTML报告启动一个本地服务器。使用你的浏览器,导航到 [http://localhost:9323](http://localhost:9323)来查看HTML报告:

Html Report For Playwright React Component Tests Showing Successful Test Results Tagged With Tested Browser Names And Time To Complete Test

在这一点上,你已经看到使用React构建的组件是如何直接使用Playwright进行测试的。让我们进一步为项目中的vue-components 应用程序设置Playwright。

为Vue组件设置Playwright组件测试

在上一节中,你在react-components 应用程序中使用Playwright来测试SearchField 组件。

在本节中,你将在vue-components 应用程序中以类似的方式使用Playwright来测试Character 组件,该组件显示Rick and Morty API中单个角色的详细信息。

执行下一个命令,将你的终端目录改为vue-components 目录,并运行Playwright安装程序:

cd ../vue-components

yarn create playwright --ct

对于安装提示,确保选择Vue作为前端框架。选择Vue将导致Playwright CLI自动安装@playwright/experimental-ct-vue 包,用于编写组件测试。

在接下来的步骤中,你将在vue-components 应用程序中为Character 组件编写两个测试。Character 组件在一个网格列表中呈现,使用从父组件接收的道具显示图片和Rick and Morty角色的一些细节。

下图中的高亮框显示了Character 组件的一个例子:

Playwright Component Testing Project Frontend With Red Box And Arrow Showing Vue Character Component To Be Tested

为Vue编写Playwright组件测试

vue-components/src 目录中创建一个名为tests 的目录。正如你对react-components 应用程序所做的那样,vue-components 的测试文件也将存储在测试目录中。

在测试目录下创建一个Character.spec.js 文件,以存储Character 组件的测试案例。

将下面的代码块内容添加到Character.spec.js 文件中,以断言Character 组件将传入该组件的道具显示为字符的细节:

import { test, expect } from '@playwright/experimental-ct-vue';
import Character from '../components/Character.vue'

const SAMPLE_CHARACTER = {
    "name": "Toxic Rick",
    "gender": "Male",
    "specie": "Humanoid",
    "type": "Rick's Toxic Side",
    "link": "https://rickandmortyapi.com/api/location/64",
    "image": "https://rickandmortyapi.com/api/character/avatar/361.jpeg"
}

test('Component displays character details from props', async ({ mount }) => {
    const characterComponent = await mount(Character, {
        props: { ...SAMPLE_CHARACTER }
    });


       await expect(characterComponent.locator('#character-name')).toHaveText(SAMPLE_CHARACTER.name);
  
   await expect(characterComponent.locator('#character-gender')).toHaveText(SAMPLE_CHARACTER.gender);
  
   await expect(characterComponent.locator('#character-type')).toHaveText(SAMPLE_CHARACTER.type);
  
   await expect(characterComponent.locator('#character-specie')).toHaveText(SAMPLE_CHARACTER.specie);

});

上面的代码包含了一个角色的样本字段的对象,类似于从对Rick and Morty API的实际请求中获取的内容。

接下来,添加下面的第二个测试案例,以断言Character 组件通过具有href属性的锚元素显示角色的名字:

test('Character name renders anchor link to character', async ({ mount }) => {
    const characterComponent = await mount(Character, {
        props: { ...SAMPLE_CHARACTER }
    });

   
   await expect(characterComponent.locator('#character-name > a') ).toHaveAttribute("href")

});

现在,执行test-ct 命令来运行你用上面两个代码块创建的两个Playwright测试案例:

yarn test-ct

和上一节一样,然后你应该能够看到你的测试结果,并为你的测试生成一个HTML报告。

为Svelte组件设置Playwright组件测试

在本文的前几节中,你已经在React和Vue应用程序中使用了Playwright,现在你在Svelte应用程序中使用Playwright。

首先,执行以下命令,将你的终端目录改为svelte-components ,并运行Playwright安装程序:

cd ../svelte-components

yarn create playwright --ct

当你通过安装提示时,确保选择Svelte作为前端框架。选择Svelte将导致Playwright自动安装@playwright/experimental-ct-svelte

在下一部分,你将为Paginator 组件编写两个测试用例,该组件将显示页码的下拉菜单。当用户点击Paginator 组件中列出的页面时,他们将被带到查看该页面上列出的字符,如下图所示。

Playwright Component Testing Project Frontend With Red Box And Arrow Showing Svelte Paginator Component To Be Tested

为Svelte编写Playwright组件测试

svelte-components/src 目录下创建一个名为tests 的目录,以存储包含你的Playwright测试案例的文件。

接下来,在tests 目录下创建一个Paginator.spec.js 文件,以存储Paginator 组件的测试用例。

将下面的代码块的内容添加到Paginator.spec.js 文件中。这段代码将创建一个测试用例,断言Paginator 组件将根据通过pagesCount 道具传递的数字显示选项元素:

import { test, expect } from '@playwright/experimental-ct-svelte'
import Paginator from '../src/components/Paginator.svelte'

test('Displays pages option based on pagesCount prop', async ({ mount }) => {
    const component = await mount(Paginator, {
        props: {
            pagesCount: 42
        }
    })

   expect(await component.locator('#pages-option > option').count()).toBe(42)})
})

添加下面的第二个测试用例,断言当点击选项时,Paginator组件的handlePageSelect 道具会返回一个数字,以按数字分页显示Rick and Morty字符:

test('`handlePageSelect` prop returns the pages number when clicked', async ({ mount }) => {
    let pageClicked;
    const component = await mount(Paginator, {
        props: {
            handlePageSelect: number => pageClicked = number,
            pagesCount: 10,
        }
    })

    await component.locator('#pages-option > option').first().click()                                                        
    expect(pageClicked).toBe(1)
})

最后,运行test-ct Paginator组件的两个测试用例:

yarn test-ct

Result Of Executing Playwright Component Testing For Svelte Components Showing Six Passed Test Result And Instructions To Open Html Report

这就是了!

在通过Svelte应用程序的这些最后的Playwright组件测试后,你已经成功地使用了Playwright的组件测试功能来测试这个示例项目中的React、Vue和Svelte应用程序。

关于Playwright组件测试的最终想法

在本教程的开始,你着手学习如何用Playwright测试你的前端组件。

该教程解释了什么是Playright组件测试功能,并带你通过使用一个包含React、Vue和Svelte组件的monorepo项目进行组件测试的实践。

如前所述,重要的是要记住,Playwright的组件测试功能相对较新,仍被认为是实验性的。它还没有对Angular的支持,与其他已经存在多年的测试工具相比,你可能会发现有些断言对Playwright是不可用的。