如何使用 Playwright 和 Docker 运行端到端测试

作者选择了 开源精神疾病以作为 写给捐赠计划的一部分获得捐赠。

介绍

Playwright是用于跨浏览器的端到端测试的绝佳工具,包括 Chromium, FirefoxWebkit。由于Webkit是Safari浏览器的核心,Playwright的跨浏览器功能使其成为测试Web应用的好选择。Playwright具有与浏览器的自动支持交互功能,因此您不必手动安装Web驱动程序,并且它支持多个编程语言,如 Java, PythonNodeJS.Playwright的灵活性意味着它可以作为Web扫描工具或端到端测试,以确保软件满足其要求。

要运行 Playwright,您需要一个适当的环境,例如 NodeJS 运行时间、 Playwright 核心框架或 Playwright 测试运行器. 您的操作系统可能需要依赖性来支持 Playwright。

在本教程中,您将设置一个环境来使用Playwright with Typescript进行端到端测试,编写和执行测试,以多种形式导出测试报告,并使用Docker部署测试。

前提条件

要跟随这个教程,你需要:

步骤 1 — 准备环境

在实施端到端测试之前,您必须准备Playwright项目环境。

首先,为此项目创建一个文件夹:

1mkdir playwright-with-docker

移动到新文件夹:

1cd playwright-with-docker

然后启动一个新的 Node 环境:

1npm init

您将被要求为新项目提供信息,例如项目名称、版本、应用程序的输入和测试命令。

您将被要求输入有关新项目的以下提示的答案:

 1[secondary_label Output]
 2package name: (playwright-docker)
 3version: (1.0.0)
 4description:
 5entry point: (index.js)
 6test command:
 7git repository:
 8keywords:
 9author:
10license: (ISC)

你会看到这样的结果:

 1[secondary_label Output]
 2This utility will walk you through creating a package.json file.
 3It only covers the most common items, and tries to guess sensible defaults.
 4
 5See `npm help init` for definitive documentation on these fields
 6and exactly what they do.
 7
 8Use `npm install <pkg>` afterward to install a package and
 9save it as a dependency in the package.json file.
10
11Press ^C at any time to quit.
12package name: (test) playwright-docker
13version: (1.0.0)
14description: A project for using playwright for end-to-end testing purpose with docker for deployment
15entry point: (index.js)
16test command:
17git repository:
18keywords:
19author: 
20license: (ISC)
21About to write to /your-path/test/package.json:
22
23{
24  "name": "playwright-docker",
25  "version": "1.0.0",
26  "description": "A project for using playwright for end-to-end testing purpose with docker for deployment",
27  "main": "index.js",
28  "scripts": {
29  "test": "echo \"Error: no test specified\" && exit 1"
30  },
31  "author": 
32  "license": "ISC"
33}
34
35Is this OK? (yes) yes

添加所需信息后,键入或按输入,以确认对package.json文件的设置。

接下来,安装该项目所需的依赖:

1npm install --save-dev playwright
2npm install --save-dev typescript

这些命令在样本项目中安装 Playwright 和 TypeScript. 旗帜 --save-dev 用于安装非应用程序运行义务的依赖性。

接下来,为 Node.JS 安装类型定义:

1npm install --save-dev @types/node

接下来,安装一个库以使用 TOML文件进行配置:

1npm install --save-dev toml

TOML 是用于应用程序配置的文件类型之一..toml 文件是人类可读的,允许应用程序在不先阅读的情况下更新其内容。

接下来,为主机系统安装Playwright依赖:

1npx playwright install-deps

当被提示时,输入你的sudo密码。

<$>[注] 注: 如果您收到一个消息,表示您需要将 Node 版本升级到更高版本,如下:

1[secondary_label Output]
2You are running Node.js 10.19.0.
3Playwright requires Node.js 12 or higher. 
4Please update your version of Node.js.

您可以使用这些命令升级:

1sudo npm cache clean -f 
2sudo npm install -g n 
3sudo n stable

npm 缓存清洁 -f 将强制清除所有缓存,而 npm install -g nn stable 将在您的服务器上安装 Node.js 稳定版本。

然后,安装Playwright测试运行器,您将在本教程的后续步骤中使用:

1npm install --save-dev @playwright/test

最后,安装支持的Playwright浏览器:

1npx playwright install

使用此命令,您可以使用多个浏览器运行测试。

要准备TypeScript配置文件,请使用nano或您喜爱的文本编辑器打开tsconfig.json:

1sudo nano tsconfig.json

目前的文件是空的. 若要为此项目更新,请添加以下代码:

1[label tsconfig.json]
2{
3  "compilerOptions": {
4    "strict": true,
5    "module": "commonjs"
6  },
7  "include": ["tests"]
8}

一个tsconfig.json文件告诉NodeJS运行时,当前的目录是Typescript项目。compilerOptions列出了NodeJS需要编译项目的条件。模块告诉编译器在编译文件时使用哪个模块语法。设置为true严格字段将允许对Typescript代码进行类型检查,这保证类型将匹配变量或方法的数据值。包括将显示应用程序中包含的文件名称或模式的列表。

保存并关闭文件完成后。

随着环境的设置,您现在可以开始构建测试。

步骤2 — 编写测试

使用您在第一步准备的 Playwright 测试环境,您现在将编写与 DigitalOcean Droplets Page相关的三个示例测试。

您将构建的 TypeScript 测试将验证以下三个项目:

  • 檢查三個選項來註冊新的 DigitalOcean 帳戶:『電子郵件登入』、『Google 登入』、『Github 登入』
  • 檢查 DigitalOcean 是否支援兩種類型的包:基本和高級
  • 檢查有四個基本的虛擬機器成本: 1 個 CPU, 2 個 CPU, 4 個 CPU, 8 個 CPU。

虽然您可以在相同的测试文件中拥有所有三个测试,但本教程将使用三个单独的文件,因为每个测试都有不同的目的。

创建一个名为测试的新目录,存储所有测试文件:

1mkdir tests

然后导航到测试目录:

1cd tests

由于您将运行三个不同目的的测试,您将在此步骤中创建三个单独的测试文件,这些文件都位于项目中的测试目录中:

  • signUpMethods.spec.ts 将实施测试,以验证用户登录的支持方法的数量.
  • multiplePackages.spec.ts 将执行测试,以验证客户可以选择的包数量
  • pricingComparison.spec.ts 将验证基本虚拟机成本的数量

<$>[注] **注:测试文件的默认格式为 *.spec.ts (对于TypeScript 项目) 或 *.spec.js (对于 JavaScript 项目)。

测试的配置文件将被命名为configTypes.ts,并在测试目录中放置。 在此文件中,您将定义与多个浏览器及其页面进行交互的全球变量。您还将定义测试中使用的某些配置值,例如正在测试的应用程序的URL。本教程将使用DIGITAL_OCEAN_URL用于测试的 URL。

创建configTypes.ts:

1nano configTypes.ts

将以下代码添加到当前空的 configTypes.ts 文件中:

 1[label configTypes.ts]
 2import { Browser, Page } from "playwright";
 3
 4import fs from 'fs';
 5import toml from 'toml';
 6const config = toml.parse(fs.readFileSync('./config.toml', 'utf-8'));
 7
 8declare global {
 9  const page: Page;
10  const browser: Browser;
11  const browserName: string;
12}
13
14export default {
15  DIGITAL_OCEAN_URL: config.digital_ocean_url ?? '',
16  };

首先,导入函数读取项目主目录中的./config.toml中的配置内容。

您声明页面浏览器浏览器名称的全球变量,这些变量将用于在端到端测试中初始化页面和浏览器实例。

最后,您将DIGITAL_OCEAN_URL导出以从./config.toml读取的值为digital_ocean_url键,这样您可以在以后的测试中使用此URL。

保存并关闭文件完成后。

对于第一个测试,使用nano或您喜爱的文本编辑器创建并打开signUpMethods.spec.ts文件:

1nano signUpMethods.spec.ts

将以下代码添加到空的文件中:

 1[label signUpMethods.spec.ts]
 2import endpoint from "./configTypes"
 3import { test, expect } from '@playwright/test'
 4
 5test("Expect to have 3 options for signing up", async ({ page }) => {
 6
 7  // Go to the Droplets product page of DigitalOcean web page
 8  await page.goto(endpoint.DIGITAL_OCEAN_URL);
 9
10  // Wait for the page to load
11  await page.waitForLoadState('networkidle');
12
13  // Get the number of signUp options
14  const number_subscriptions_allowed = await page.locator('.SignupButtonsStyles__ButtonContainer-sc-yg5bly-0 > a').count()
15
16  // Verify that number equals 3
17  expect(number_subscriptions_allowed).toBe(3)
18});

signUpMethods.spec.ts文件包含测试的代码,它评估了 Droplets 页面是否有三个注册选项。

测试可以以无同步方式或同步方式编写。以无同步方式编写测试有助于优化测试的速度,因为您不必等待测试中的每个步骤完成以执行下一步。当您需要等待步骤完成之前,您需要使用等待关键字。由于此处的步骤与网络交互有关,您需要确保在执行操作之前显示用户界面中的每个元素,这就是为什么您在呼叫每个操作之前包括等待方法。

测试被定义为测试块,有四个操作。第一个等待关键字使用page.goto()函数来告诉测试进入DIGITAL_OCEAN_URL,这是在configTypes.ts文件中定义的。

第二个等待关键字告诉测试使用page.waitForLoadState()函数等待页面加载,如果有未完成的API调用,则页面上可能有不可用元素,因此测试可能会失败,因为它无法找到该元素。

您定义了 number_subscriptions_allowed 来使用 page.locator() 函数来搜索登录选项的数量. 您可以通过 CSS 选择器(在这种情况下,登录按钮)找到 signUp 选项 组件,从而获取其中包含的儿童元素的数量。

最后,一个期望方法将验证由page.locator()找到的选项数量,预计输出为3

保存并关闭文件。

接下来,你会写第二个测试. 创建并打开 multiplePackages.spec.ts 文件:

1nano multiplePackages.spec.ts

在空的文件中,添加以下代码:

 1[label multiplePackages.spec.ts]
 2import endpoint from "./configTypes"
 3import { test, expect } from '@playwright/test'
 4
 5test("Expect to have 3 packages for subscription", async ({ page }) => {
 6
 7  // Go to the Droplets product page of DigitalOcean web page
 8  await page.goto(endpoint.DIGITAL_OCEAN_URL);
 9
10  // Wait for the page to load
11  await page.waitForLoadState('networkidle');
12
13  // Get the number of packages to be 2 (Basic and Premium)
14  const number_subscriptions_allowed = await page.locator('.CPUInfoStyles__StyledLeftCpuInfo-sc-ooo7a2-4 > div').count()
15
16  // Verify that number equals 2
17  expect(number_subscriptions_allowed).toBe(2)
18});

类似于signUpMethods.spec.ts文件,您将从Playwright依赖中导入测试配置和测试功能。

在此测试中,您首先使用page.goto()进入DIGITAL_OCEAN_URL,然后等待页面以page.waitForLoadState()完成所有网络调用。

您可以在 Web UI 中找到订阅组件的子元素,并将该信息存储在 number_subscriptions_allowed 变量中。

最后,您将 number_subscriptions_allowed' 的值与 2' 的预期输出进行比较。

保存并关闭文件完成后。

然后,创建并打开pricingComparison.spec.ts文件来定义第三个测试:

1nano pricingComparison.spec.ts

将以下代码添加到空的文件中:

 1[label pricingComparison.spec.ts]
 2import endpoint from "./configTypes"
 3import { test, expect } from '@playwright/test'
 4
 5test("Expect to have 3 packages for subscription", async ({ page }) => {
 6
 7  // Go to the Droplets product page of DigitalOcean web page
 8  await page.goto(endpoint.DIGITAL_OCEAN_URL);
 9
10  // Wait for the page to load
11  await page.waitForLoadState('networkidle');
12
13  // Get the number of basic virtual machine costs (1 CPU, 2 CPU, 4 CPU, 8 CPU)
14  const number_subscriptions_allowed = await page.locator('.PricingComparisonToolStyles__StyledCpuSelector-sc-1k0sndv-7 > button').count()
15
16  // Verify that number equals 4
17  expect(number_subscriptions_allowed).toBe(4)
18});

此测试中的 async 函数使用相同的 page.goto() URL 和 page.waitForLoadState() 指令,就像在以前的测试中一样。

对于此测试,您可以获取定价选项组件的子元数,并将该值存储在number_subscriptions_allowed变量中,您验证number_subscriptions_allowed的值必须等于4(当前支持的订阅数)。

保存并关闭文件。

在测试中,您将从configTypes.ts中使用DIGITAL_OCEAN_URL,而configTypes.ts则从./config.toml文件中读取digital_ocean_url值。

现在,您将在项目的主目录中创建 config.toml 文件. 导航到主目录:

1cd ..

然后创建config.toml文件:

1nano config.toml

将下列内容复制到 config.toml 文件:

1[label config.toml]
2digital_ocean_url="https://www.digitalocean.com/products/droplets"

保存并关闭文件。

该项目的目录树现在将看起来像这样:

Directory tree showing each of the files in the project, including the three Typescript files created within the <code>tests</code> folder

在此步骤中,您写下了您将使用的三个测试,您还定义了测试所依赖的 config.toml 文件,您将在下一步执行测试。

步骤 3 — 执行测试

使用 Playwright test runner in the CLI的选项有很多,例如在所有浏览器中运行所有测试,禁用并行化,运行一组测试文件,并在调试模式中运行,等等。

首先,运行这个命令:

1npx playwright test --browser=all

您应该能够看到测试结果如下:

 1[secondary_label Output]
 2Running 9 tests using 1 worker
 3
 4  ✓  [chromium] › tests/multiplePackages.spec.ts:4:1 › Expect to have 3 packages for subscription (6s)
 5  ✓  [chromium] › tests/pricingComparison.spec.ts:4:1 › Expect to have 3 packages for subscription (4s)
 6  ✓  [chromium] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (3s)
 7  ✓  [firefox] › tests/multiplePackages.spec.ts:4:1 › Expect to have 3 packages for subscription (9s)
 8  ✓  [firefox] › tests/pricingComparison.spec.ts:4:1 › Expect to have 3 packages for subscription (5s)
 9  ✓  [firefox] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (7s)
10  ✓  [webkit] › tests/multiplePackages.spec.ts:4:1 › Expect to have 3 packages for subscription (7s)
11  ✓  [webkit] › tests/pricingComparison.spec.ts:4:1 › Expect to have 3 packages for subscription (6s)
12  ✓  [webkit] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (6s)
13
14  9 passed (1m)

检查标志表明,所有测试都通过了三个浏览器(Chromium,Firefox和Webkit)。

工人的数量将取决于当前服务器使用的核心数量和测试的当前配置. 您可以通过在 playwright.config.ts 文件中设置工人值来限制工人的数量。

Playwright 测试运行器为测试报告提供了几个选项,可以集成到 CI 工具中,例如 JenkinsCircleCI.有关测试报告的更多信息,请参阅 Playwright 测试记者文档页面

对于本教程,您将使用HTML报告文件运行测试,这比在CLI中查看测试更容易阅读。

运行此命令为 HTML 测试报告:

1npx playwright test --browser=all --reporter=html

你会看到这样的结果:

1[secondary_label Output]
2Running 9 tests using 2 workers
3
4  9 passed (40s)
5
6To open last HTML report run:
7
8  npx playwright show-report

要查看 HTML 报告,请运行:

1npx playwright show-report

你会看到这样的输出:

1[secondary_label Output]
2Serving HTML report at http://your_ip_address:9323. Press Ctrl+C to quit.

您现在应该能够通过端口9323访问您的报告。

<$>[注] :如果您正在远程访问服务器,则需要将远程服务器暴露在当前的本地机器上,以便在本地浏览器中查看测试报告。

1[environment local]
2ssh -L 9323:localhost:9323 your_non_root_user@your_server_ip

SSH 端口转发将服务器端口转发到本地端口. -L 9323:localhost:9323 部分识别到本地计算机上的端口 `9323' 将转发到远程服务器上的相同端口。

您现在应该能够通过在本地计算机上的浏览器中导航到http://localhost:9323来查看测试报告。

当你的报告在浏览器中加载时,你会注意到每个测试在三个浏览器上运行:Chromium,Firefox和Webkit.你会知道每个测试在每个浏览器上运行需要多长时间,以及整个测试需要多长时间。

Screencapture of the overall report, which is separated into the three different tests where each test displays the overall time the test took to run, as well as how long each browser's test took to run

点击报告名称查看详细信息。

Screencapture of the report details for the <code>signUpMethods.ts</code> test, which displays the length of time that each element of the test took

在细节部分中,测试执行步骤将默认情况下包含Before HooksAfter Hooks步骤。Before Hooks部分通常用于初始设置,例如登录控制台或阅读测试数据。在测试完成后,After Hooks部分通常会清理测试环境中的测试数据。测试中每个步骤都有详细信息,包括使用page.goto()访问URL,等待页面加载page.waitForLoadState(),用locator.count()计算登录方法,并验证值匹配expect.toBe等。

在此步骤中,您运行了所有三个测试,审查了它们的通过状态,并在 CLI 和 HTML 格式中查看了测试结果。

步骤 4 — 使用 Docker 部署测试

在实施测试自动化时,您可能面临环境问题. 一些测试将在测试工程师的本地机器中按照预期运行,但在集成到 CI/CD 管道时由于环境兼容性问题而失败。

首先,您将更新「package.json」文件,添加必要的测试脚本,然后在Docker中运行。

1nano package.json

将突出列出的行添加到package.json文件中的脚本部分:

1[label package.json]
2...
3 "scripts": {
4  "test": "playwright test --browser=all",
5  "test-html-report": "playwright test --browser=all --reporter=html",
6  "test-json-report": "PLAYWRIGHT_JSON_OUTPUT_NAME=results.json playwright test --browser=chromium --reporter=json"
7  },

这些脚本将运行自定义测试,而不是输入完整的命令. 当您需要使用HTML的记者显示器运行测试时,您现在将能够运行此命令:

1npm run test-html-report

代替全方位指挥:

1npx playwright test --browser=all --reporter=html

您的当前package.json将看起来像这样:

 1{
 2  "name": "playwright-docker",
 3  "version": "1.0.0",
 4  "description": "A project for using playwright for end-to-end testing purpose with docker for deployment",
 5  "main": "index.js",
 6  "scripts": {
 7  "test": "playwright test --browser=all",
 8  "test-html-report": "playwright test --browser=all --reporter=html",
 9  "test-json-report": "PLAYWRIGHT_JSON_OUTPUT_NAME=results.json playwright test --browser=chromium --reporter=json"
10  },
11  "author": "",
12  "license": "ISC",
13  "devDependencies": {
14  "@playwright/test": "^1.22.2",
15  "@types/node": "^17.0.35",
16  "playwright": "^1.22.1",
17  "toml": "^3.0.0",
18  "typescript": "^4.6.4"
19  }
20}

保存并关闭文件。

接下来,在当前目录中创建并打开 Dockerfile:

1nano Dockerfile

然后添加以下内容:

 1[label Dockerfile]
 2# Get the base image of Node version 16
 3FROM node:16
 4
 5# Get the latest version of Playwright
 6FROM mcr.microsoft.com/playwright:focal
 7
 8# Set the work directory for the application
 9WORKDIR /app
10
11# Set the environment path to node_modules/.bin
12ENV PATH /app/node_modules/.bin:$PATH
13
14# COPY the needed files to the app folder in Docker image
15COPY package.json /app/
16COPY tests/ /app/tests/
17COPY tsconfig.json /app/
18COPY config.toml /app/
19
20# Get the needed libraries to run Playwright
21RUN apt-get update && apt-get -y install libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev libatspi2.0-0 libxshmfence-dev
22
23# Install the dependencies in Node environment
24RUN npm install

首先,您可以将 Node 版本 16 和 Playwright 版本的基本图像焦点放入您的 Docker 图像中,测试需要运行 Node 和 Playwright。

然后,您将项目目录名称设置在容器中. 在这种情况下,它是WORKDIR。设置WORKDIR /app将您的所有文件放入容器内的/app目录中。

您将 Docker 容器的环境路径设置为 ENV PATH. 在这种情况下,您将其设置为 node_modules 目录。

然后,您将所有必要的文件复制到Docker图像中的/app目录。

由于Playwright需要一些依赖性来运行,所以你也会在Docker图像中安装这些依赖性。

保存并关闭文件。

接下来,您将为您的自动化项目构建图像:

1docker build -t playwright-docker .

Docker 會在現行目錄中找到「Dockerfile」並根據「Dockerfile」內部的指示建立圖像。「-t」旗標記 Docker 圖像,並將其命名為「playwright-docker」。

构建输出(缩短为简短)将看起来像这样:

 1[secondary_label Output]
 2Sending build context to Docker daemon 76.61MB
 3...
 4added 6 packages, and audited 7 packages in 6s
 5
 6found 0 vulnerabilities
 7Removing intermediate container 87520d179fd1
 8 ---> 433ae116d06a
 9Successfully built 433ae116d06a
10Successfully tagged playwright-docker:latest

测试可能不会在 Windows 或 MacOS 上正常运行,因为在初始安装过程中存在冲突依赖或缺少依赖,但使用 Docker 来运行测试应该防止这些环境配置问题。

查看 Docker 图像是否成功创建:

1docker image ls

结果应该是这样的:

1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3playwright-docker latest 433ae116d06a 5 minutes ago 1.92GB
4mcr.microsoft.com/playwright focal bb9872cfd272 2 days ago 1.76GB
5node 16 c6b745e900c7 6 days ago 907MB

您将有playwright-docker(测试图像),microsoft playwrightnode图像,您还可能有ubuntuhello-world的图像从Docker安装前提条件。

现在,使用docker run在您的 Docker 容器中运行测试命令:

1docker run -it playwright-docker:latest npm run test

在此示例中,图像为playwright-docker:latest,命令为npm run testdocker run将首先引入 Docker 容器,然后运行所需的命令。

结果将是这样的:

 1[secondary_label Output]
 2> [email protected] test
 3> playwright test --browser=all
 4
 5Running 9 tests using 2 workers
 6
 7  ✓  [chromium] › tests/pricingComparison.spec.ts:4:1 › Expect to have 4 pricing options (7s)
 8  ✓  [chromium] › tests/multiplePackages.spec.ts:4:1 › Expect to have 2 packages for subscription (8s)
 9  ✓  [chromium] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (8s)
10  ✓  [firefox] › tests/multiplePackages.spec.ts:4:1 › Expect to have 2 packages for subscription (9s)
11  ✓  [firefox] › tests/pricingComparison.spec.ts:4:1 › Expect to have 4 pricing options (8s)
12  ✓  [firefox] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (5s)
13  ✓  [webkit] › tests/multiplePackages.spec.ts:4:1 › Expect to have 2 packages for subscription (8s)
14  ✓  [webkit] › tests/pricingComparison.spec.ts:4:1 › Expect to have 4 pricing options (10s)
15  ✓  [webkit] › tests/signUpMethods.spec.ts:4:1 › Expect to have 3 options for signing up (7s)
16
17  9 passed (41s)

您可以安全地 更新代码到远程存储库,系统管理员可以 整合自动化测试到CI/CD管道

您也可以查看本文中创建的文件在 此存储库中。

结论

您已使用 Playwright 进行端到端测试,并使用 Docker 部署了测试。 有关 Playwright 的更多信息,请访问 Playwright 文档

您可以阅读有关 Docker 生态系统(https://andsky.com/tech/tutorials/the-docker-ecosystem-an-introduction-to-common-components)的信息,以了解更多关于 Docker 的信息。 Docker 产品文档还包含一些 写 Dockerfiles 的最佳做法Dockerfile 参考指南. 要继续使用 Docker,您可以尝试 其他 Docker 教程

Published At
Categories with 技术
comments powered by Disqus