
测试是软件开发中的必修课,有许多可行的工具来完成这项任务。本文将探讨 Puppeteer 如何使自动化测试变得简单而有效,并将教您如何为 React 应用程序编写简单、高效的 E2E 测试,以及如何使用 Puppeteer 从用户角度进行测试。
软件测试是软件开发生命周期(SDLC)的一个重要方面。对应用程序进行测试势在必行,因为这样做可以帮助您及早发现编写代码中的错误和缺陷,并使您能够构建符合预期的高质量标准软件。
然而,许多组织仍然严重依赖效率低下的手动测试 *** 。统计数据为实施更多的自动化测试提供了令人信服的理由。研究表明,的,但只有 5% 的公司进行了完全自动化的测试。三分之二的公司以 的比例进行测试。
预计 2021-2026 年间,,因此测试自动化是跟上市场步伐的关键。一项研究发现,79% 的最终用户在 2019 年仍会遇到错误,这表明需要更好的测试。70% 的 IT 领导者肯定自动化测试能带来更高的效率,因此自动化趋势只增不减。 等解决方案可实现简化的端到端(E2E)测试,帮助组织和公司提高软件质量和用户体验。
是谷歌开发的一个 Node.js 库,用于自动化前端测试过程。它提供高级 API,可通过 协议控制 Chrome 浏览器或基于 Chromium 的浏览器。它允许测试人员执行无头和有头操作。
无头浏览器是一种没有图形用户界面(GUI)的浏览器。它们通过命令行界面或 *** 通信执行。-
Puppeteer 允许以无头模式(不显示浏览器用户界面)或有头模式(显示浏览器用户界面)控制 Chrome 或 Chromium。虽然无头模式是默认模式,但有头模式也有助于调试。与无头模式浏览器相比,网站也更难检测到由脚本控制的有头模式浏览器。
Puppeteer 的应用领域:
是一个开源 ,旨在测试 React 和 React Native *** 应用程序。
通常,软件前端的 E2E 测试过于繁琐,因为需要进行大量耗时的配置。然而,使用 Jest 进行测试可以更大限度地减少单元测试所需的配置,从而降低前端测试的复杂性。
在本节中,你将使用 Puppeteer 和 Jest 配置一个。首先,你将使用引导一个新的 React 应用程序。
运行以下命令:
npx create-react-app react-puppeteer-test
接下来,创建项目目录和 react-puppeteer-test 应用程序后,导航到新创建的目录,并在终端运行以下命令安装以下软件包:
npm install puppeteer jest jest-puppeteer
设置好应用程序后,在终端中输入以下任一命令运行应用程序:

yarn start
或使用 :
npm start
服务器应在浏览器 http://localhost:3000/ 中启动,如下图所示:

Jest 默认情况下运行良好,但有时您需要更多配置功能。首先,在项目根目录下创建一个名为 jest.config.js 的文件,设置 Jest 配置。用以下代码段填充该文件:
module.exports = {
preset: "jest-puppeteer",
testMatch: ["**/src/__tests__/**/*.test.js"],
verbose: true,
};
此配置指示 Jest 使用 jest-puppeteer 预设,并将测试放在 __tests__ 文件夹中。
在 package.json 文件中添加相应的脚本:
"scripts": {
"test": "jest"
}
该命令指示 Jest 处理测试脚本。您已在应用程序中成功配置了 Jest。
接下来,在项目根文件夹中创建一个名为 jest-puppeteer.config.js 的文件,并粘贴以下代码段以创建 Puppeteer 配置:
module.exports = {
launch: {
headless: process.env.HEADLESS !== "false",
slowMo: process.env.SLOWMO ? parseInt(process.env.SLOWMO, 10) : 0,
devtools: process.env.DEVTOOLS === "true",
product: "chrome",
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--disable-accelerated-2d-canvas",
"--disable-gpu",
"--window-size=1920,1080",
],
},
};
该配置规定在无头模式下运行 Puppeteer,避免使用沙箱,禁用 GPU 并设置窗口大小。它还允许自定义浏览器产品(Chrome 或 Firefox),并引入了减缓测试执行速度以提高可视性的选项。
关于使用 Puppeteer 和 Jest 进行的基本测试,请参考以下使用示例。
在本教程中,我将指导你使用 Puppeteer 进行之一次自动测试。如果你阅读了本节内容,说明你已经在项目中安装并设置了 Puppeteer。如果还没有,请按照上面的说明操作。如果你已经安装,那就让我们开始吧。
创建测试文件。你必须创建实际的测试文件来进行测试。为此,您必须在某些目录中合理安排测试文件的结构。在终端运行以下命令:
cd src && mkdir __tests__ && cd __tests__ && touch homepage.test.js
上述命令的作用是
src 文件夹;__tests__ 文件夹;homepage.test.js 的新文件// src/__tests__/homepage.test.js
const puppeteer = require("puppeteer");
describe("OpenReplay.com page", () => {
let browser;
let page;
beforeAll(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
it("should contain text", async () => {
await page.goto("https://openreplay.com/", { waitUntil: 'networkidle2' });
await page.waitForSelector(".display-4");
const text = await page.$eval(".display-4", (e) => e.textContent);
expect(text).toContain(`Session replay`);
});
afterAll(() => browser.close());
});
上面这段代码的作用是
display-4 类是否包含网站上的 Session replay 文本。beforeAll 函数启动 Puppeteer 实例,创建浏览器和页面。测试使用页面的选择器检查是否存在指定文本。
这可以作为创建自定义测试的模板。现在,让我们来探讨一个实际场景。
考虑一个登录表单组件:
// App.js
import { useState } from "react";
import "./App.css";
function App() {
const [isUserLoggedIn, setIsUserLoggedIn] = useState(false);
const [error, setError] = useState(false);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const login = (event) => {
event.preventDefault();
if (email === "admin@openreplay.com" && password === "password") {
setIsUserLoggedIn(true);
} else {
setIsUserLoggedIn(false);
setError(true);
setTimeout(() => {
setError(false);
}, 4000);
}
};
return (
<div className="App">
<div className="form-wrapper">
<h1 className="form-header">Welcome back</h1>
{!isUserLoggedIn && (
<form className="form" onSubmit={login}>
{error && (
<p className="form-error-text">
Invalid email or password
</p>
)}
<input
type="email"
required
placeholder="Email Address"
className="form-input form-input__email"
onChange={(e) => {
setEmail(e.target.value);
}}
name="emailAddress"
/>
<input
type="password"
required
placeholder="Password"
className="form-input form-input__password"
onChange={(e) => {
setPassword(e.target.value);
}}
name="password"
/>
<button type="submit" className="form-submit-button">
Submit
</button>
</form>
)}
{isUserLoggedIn && (
<p className="form-success-message">Login successful.</p>
)}
</div>
</div>
);
}
export default App;
在上面的代码中,我们模拟了一个登录场景:
isUserLoggedIn、 error、 email 和 password。login 函数处理表单提交、检查凭证并相应更新状态。admin@openreplay.com 且密码是 password 时,登录才会成功。
// App.test.js
import puppeteer from "puppeteer";
describe("App.js", () => {
let browser;
let page;
beforeAll(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
it("shows a success message after submitting a form", async () => {
await page.goto("http://localhost:5000");
await page.waitForSelector(".form-header");
await page.click(".form-input__email");
await page.type(".form-input__email", "admin@openreplay.com");
await page.click(".form-input__password");
await page.type(".form-input__password", "password");
await page.click(".form-submit-button");
await page.waitForSelector(".form-success-message");
const text = await page.$eval(
".form-success-message",
(e) => e.textContent
);
expect(text).toContain("Login successful.");
});
it("shows an error message if authentication fails", async () => {
await page.goto("http://localhost:5000");
await page.waitForSelector(".form-header");
await page.click(".form-input__email");
await page.type(".form-input__email", "admin@openreplay.com");
await page.click(".form-input__password");
await page.type(".form-input__password", "password123");
await page.click(".form-submit-button");
await page.waitForSelector(".form-error-text");
const text = await page.$eval(".form-error-text", (e) => e.textContent);
expect(text).toContain("Invalid email or password");
});
afterAll(() => browser.close());
});
上述测试示例 ⬆ 演示了使用 Puppeteer 和 Jest 测试登录表单。它包括导航到应用程序、与表单元素交互以及验证预期结果。
beforeAll 块中的设置代码、启动 Puppeteer 浏览器实例以及在任何测试前创建新页面。it )检查使用有效凭证提交表单后是否显示成功消息(Login successful.)。Invalid email or password)来与表单交互。AfterAll 块确保在完成所有测试后关闭 Puppeteer 浏览器实例。
Puppeteer 提供了多种调试选项,可用于 React 应用程序的端到端测试。让我们来探索这些选项,并演示如何将它们整合到现有测试中。
Puppeteer 默认以无头模式启动 Chromium 浏览器,这意味着没有可见的用户界面。这非常适合自动化测试和服务器环境。不过,如果你想在测试执行期间观察浏览器,可以通过设置 headless: false 来启动完整版浏览器:
beforeAll(async () => {
browser = await puppeteer.launch({ headless: false });
page = await browser.newPage();
});
运行测试时,将显示一个 Chromium 浏览器窗口。
在无头模式下,某些操作(如表单提交)可能发生得太快,无法观察。为了解决这个问题,Puppeteer 提供了 slowMo 选项,可以延迟 Puppeteer 的执行。
例如,可按如下 *** 将速度减慢 300 毫秒:
beforeAll(async () => {
browser = await puppeteer.launch({
headless: false,
slowMo: 300, // slow down by 300ms
});
page = await browser.newPage();
});
这样就能更好地跟踪测试执行情况。
page.emulate 模拟设备使用 page.emulate() *** 可以模拟设备指标和用户 *** 。您可以自定义视口尺寸和用户 *** 等属性:
beforeAll(async () => {
browser = await puppeteer.launch({ headless: false });
page = await browser.newPage();
page.emulate({
viewport: {
width: 500,
height: 900,
},
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
isLandscape: false,
});
});
Puppeteer 为简化仿真提供了设备描述符列表,可通过 puppeteer.devices 访问。例如,模拟 iphone 7:
const iPhone = puppeteer.devices['iPhone 7'];
beforeAll(async () => {
browser = await puppeteer.launch({
headless: false,
slowMo: 300, // slow down by 300ms
});
page = await browser.newPage();
await page.emulate(iPhone);
});
Jest Puppeteer 简化了运行 Puppeteer 测试的配置。请按照以下步骤进行设置:
使用 yarn add -D jest-puppeteer 安装 Jest Puppeteer。创建 jest.config.js 文件:
module.exports = {
preset: "jest-puppeteer",
testRegex: "./*\\e2e\\.test\\.js$",
};
创建 jest-puppeteer.config.js 文件:
module.exports = {
server: {
command: "yarn start",
port: 3000,
launchTimeout: 10000,
debug: true,
},
};
Jest Puppeteer 无需在测试前构建生产网站,从而简化了测试流程。
修改测试文件(如 e2e.test.js )以利用 Jest Puppeteer 的功能:
// ... (existing setup)
describe("App.js", () => {
it("shows a success message after submitting a form", async () => {
// ... (existing test logic)
});
it("shows an error message if authentication fails", async () => {
// ... (existing test logic)
});
});
Jest Puppeteer 更大限度地减少了设置,并为表单填写、按钮点击和文本匹配提供了更简洁的语法。
运行测试前,更新 App.js 中的表单,为电子邮件和密码输入添加名称属性。
<input
type="email"
required
placeholder="Email Address"
className="form-input form-input__email"
onChange={(e) => {
setEmail(e.target.value);
}}
name="emailAddress"
/>
<input
type="password"
required
placeholder="Password"
className="form-input form-input__password"
onChange={(e) => {
setPassword(e.target.value);
}}
name="password"
更新 .eslintrc.js 文件,确保 ESLint 兼容性:
module.exports = {
env: {
jest: true,
},
globals: {
page: true,
browser: true,
context: true,
jestPuppeteer: true,
},
};
使用 yarn test:e2e 执行测试,获得所有测试通过的简明输出。
通过使用这些 Puppeteer 调试选项和 Jest Puppeteer,你可以简化测试流程,确保 React 应用程序的端到端测试功能强大。
本文深入介绍了如何使用 Puppeteer 和 Jest 进行端到端测试。实际示例展示了登录表单的测试,强调了导航、元素识别和用户操作模拟。将这些原则纳入您的测试工作流程,以实现强大的 React 应用测试。
在 上查看本文的资源库
宝塔的数据库管理,是基于phpmyadmin管理和新建数据库。其最大的便利性就是类似,通过面板可以快速访问进行管理操作,无需单独访问phpmyadmin的主页。 此外,在宝塔面板进行数据库管理,你也对数据库名、用户名及密码等信息一目了然,及可以对数据库执行快速备份或者导入。 添加数据...
宝塔面板另外一个特质是,你无需通过Linux命令行来查看服务器各项指标状况,即可以阿里云服务器类似的可视化图表,查看资源使用、负载、CPU占用及内容使用百分比等指标。 默认监控是关闭,有需要的,可以开启,监控数据默认保存30天,可以自行修改,默认监控数据保存在日志,可手动清理该日志。 监控管理,...
Laravel多年来一直是PHP应用程序开发的摇滚明星,这是有充分理由的。庞大的生态系统、活跃的社区、强大的就业市场、成功的初创公司——它拥有一切让采用新技术变得值得的东西。 如果你想学习Laravel,你不需要更进一步。通过浏览本指南,您可以找到最适合您的Laravel教程,与您的知识水平和...
美国劳工统计局估计在美有超过软件开发人员。根据2021年的数据,其中,这是世界上使用最广泛的五种编程语言之一。 自然,学习Java并成为Java开发人员对于任何对软件开发感兴趣的人来说都是明智的职业选择。 在本综合指南中,您将学习成为Java开发人员所需的一切知识。我们将分解您需要的技能、工...
无服务器计算是一种基于云的执行模型,可以将应用程序作为服务托管,而无需维护服务器。 服务提供商维护服务器上的资源分配,并根据实际使用情况向用户收费。焦点转移到一个人正在创建的核心应用程序上,基础设施完全由服务提供商处理。无服务器计算也称为功能即服务 (FaaS)。 换句话说,Serverle...
Cloudflare已宣布弃用HOST API集成,这将影响Cloudflare的传统主机和经销商合作伙伴。 Cloudflare弃用HOST API Cloudflare Legacy Host API将于2022年11月1日正式被弃用。Cloudflare表示,由于支持和维护程序...