使用Jest和TypeScript的Playwright入门指南

1,322 阅读3分钟

Playwright with Jest and TypeScript

Playwright是微软推出的一个新的端到端跨浏览器测试工具。我通常使用Cypress对SPA进行这类测试,但Playwright正在迅速获得关注,所以我认为是时候尝试一下了。

我们将介绍如何使用Jest作为测试运行器来启动和运行Playwright,以及如何设置项目,以便我们可以使用TypeScript来编写测试。在文章的最后,我们将介绍如何在VS Code中调试测试。

安装

要安装Playwright,在终端运行以下命令:

npm install --save-dev playwright

添加TypeScript

Playwright的测试默认是用JavaScript写的。为了用TypeScript写测试,我们需要在我们的项目中安装TypeScript。

npm install --save-dev typescript

让我们添加以下tsconfig.json 来配置TypeScript:

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "strict": true,
    "module": "commonjs",
    "noEmit": true
  },
  "include": ["src"]
}

这假定我们的测试文件将在src 文件夹中。

添加Jest

默认情况下,Playwright测试是用Node执行的。添加Jest给了我们一个测试运行器,它有一个很好的API。让我们来安装它:

npm install --save-dev jest

我们还需要安装ts-jest 和Jest的类型,因为我们想使用TypeScript:

npm install --save-dev ts-jest @types/jest

还有一个用于Playwright的Jest预设,我们要利用它:

npm install --save-dev jest-playwright-preset

让我们添加一个名为jest.config.js 的Jest配置文件,其内容如下:

module.exports = {
  preset: "jest-playwright-preset",
  testMatch: ["**/__tests__/**/*.+(ts|js)", "**/?(*.)+(spec|test).+(ts|js)"],
  transform: {
    "^.+\\.(ts)$": "ts-jest",
  }
};

这里我们告诉Jest使用我们刚刚安装的预设。我们还告诉它拾取TypeScript文件(以及JavaScript文件),并用ts-jest 来处理它们。

编写测试前的最后一步是添加一个npm脚本来运行package.json

{
  ...,
  "scripts": {
    "test": "jest",
    "test.watch": "jest --watchAll"
  },
  ...
}

编写一个简单的Playwright测试

我们将在这个博客的主页上写一个简单的测试。我们要检查页面的标题是否正确。

我们将Jest配置为在名称以.spec.ts.test.ts 结尾的文件中寻找测试。让我们在src 文件夹中创建一个名为home.test.ts 的文件,内容如下:

import { chromium, Browser, Page } from "playwright";

我们已经导入了chromium ,稍后我们会用它来启动Chrome。我们还为我们要交互的浏览器和页面导入了TypeScript类型。

让我们添加在测试运行前后执行的代码:

let browser: Browser;
beforeAll(async () => {
  browser = await chromium.launch();
});
afterAll(async () => {
  await browser.close();
});

这段代码将在测试运行前启动Chrome浏览器,并在测试全部结束后关闭它。

让我们添加以下代码,在每个测试前后执行:

let page: Page;
beforeEach(async () => {
  page = await browser.newPage();
});
afterEach(async () => {
  await page.close();
});

我们在每次测试前在浏览器中创建一个新标签,并在测试结束后关闭它。

现在,让我们来写我们的测试:

it("Home page should have the correct title", async () => {
  await page.goto("https://www.carlrippon.com/");
  expect(await page.title()).toBe("All posts | Building SPAs");
});

让我们通过在终端输入以下命令来运行测试:

npm test

测试成功运行:

Passing test

不错!😀

beforeAll,afterAll,beforeEach, 和afterEach 函数中的代码是我们需要在每个测试文件中编写的代码。另外,我们的测试只在Chrome上执行--理想情况下,我们希望我们的测试能在Playwright支持的所有浏览器上运行。

jest-playwright-preset 如果我们把这些代码删除,就可以轻松地在不同的浏览器上进行测试。添加以下代码到 jest.config.js

module.exports = {
  ...,
  testEnvironmentOptions: {    "jest-playwright": {      browsers: ["chromium", "firefox", "webkit"]    },  }};

我们已经指定我们的测试应该在Chromium、Firefox和Webkit上运行。

让我们删除测试中的beforeAll,afterAll,beforeEach, 和afterEach 函数。我们也不需要导入语句了。

在我们的测试中引用了page ,我们会得到一个类型错误。Jest Playwright预设已经创建了一个page ,我们可以使用,但TypeScript没有意识到这一点。

Type error on page

我们可以添加下面的全局声明来解决这个问题。在src 文件夹中添加一个名为globalTypes.ts 的文件,内容如下:

import { Browser, Page } from "playwright";

declare global {
  const page: Page;
  const browser: Browser;
  const browserName: string;
}

page,browser, 和browserName 是全局变量,我们可以在测试中使用。

现在类型错误已经解决了。 😀

让我们在终端输入npm test ,重新运行测试:

All tests passing 测试在每个浏览器类型上都能成功执行。

调试我们的测试

首先,我们将使用一些老式的方法来调试我们的测试。

我们可以使用console.log ,向控制台输出有用的信息:

it("Home page should have the correct title", async () => {
  await page.goto("https://www.carlrippon.com/");
  console.log("page title", await page.title());  expect(await page.title()).toBe("All posts | Building SPAs");
});

然后我们看到这个输出到终端:

Console log 我们还可以在测试的不同点上进行屏幕截图:

it("Home page should have the correct title", async () => {
  await page.goto("https://www.carlrippon.com/");
  await page.screenshot({ path: `./screenshots/home-${browserName}.png` });  expect(await page.title()).toBe("All posts | Building SPAs");
});

测试结束后,屏幕截图将被放置在screenshots 文件夹中。

browserName 是一个全局变量,给出了当前正在测试的浏览器的名称。

一个更有成效的调试方法是使用VS Code中的节点调试器。为了设置这个,我们首先需要在.vscode 文件夹中添加以下launch.json 文件:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Jest Tests",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/jest",
      "args": ["--runInBand"],
      "windows": {
        "program": "${workspaceFolder}/node_modules/jest/bin/jest"
      },
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

我们将我们的启动配置称为Debug Jest Tests,我们只是告诉节点进程执行Jest。

到目前为止,我们的测试一直在无头模式下运行。让我们改变一下,这样我们就可以看到浏览器被打开,页面被交互。在jest.config.js ,我们可以添加下面的启动选项来做到这一点:

module.exports = {
  ...,
  testEnvironmentOptions: {
    "jest-playwright": {
      browsers: ["chromium", "firefox", "webkit"],
      launchOptions: {        headless: false,      },    },
  },
  ...
};

让我们在测试中设置一个断点,在空白处点击我们想断的那行代码。

如果我们打开左侧面板的运行部分,我们会看到我们的配置在一个绿色的三角形图标旁边:

Run in debug mode 我们可以点击这个绿色三角形图标来启动调试器。

测试将运行,我们将看到第一个浏览器打开。最终,测试会在我们的断点上停止:

Debugging

我们可以踏过代码,观察变量,并看到调用堆栈,以快速诊断问题。

我们还可以完全访问测试所打开的浏览器中的DevTools,这对于调试视觉问题很方便。

不错,😀