Puppeteer简介
Puppeteer是一个由Google Chrome团队开发的Node库,它提供了一套高级API来控制Chrome或Chromium浏览器。Puppeteer主要用于无头浏览器的场景,但也可以配置为运行"有头"模式(即常规的浏览器界面)。通过模拟真实用户的操作,如页面导航、表单填写、按钮点击等,Puppeteer在Web自动化测试、爬虫、页面渲染等方面展现出了巨大的潜力。在自动化测试领域,Puppeteer特别受到青睐,原因在于它的灵活性、易用性和功能强大。
Chrome无头模式
Chrome无头模式是Google Chrome浏览器的一个特性,允许在没有图形用户界面的情况下运行浏览器。这意味着你可以在后台执行Web页面渲染、执行JavaScript或进行自动化测试等操作,而无需打开浏览器窗口。对于自动化测试而言,无头模式具有以下几个优点:
- 速度快:由于不需要渲染图形界面,测试执行的速度更快。
- 环境兼容:可以在没有图形界面的服务器环境中运行测试,适合持续集成(CI)环境。
- 资源占用少:相比于全模式(Full mode)浏览器,无头模式占用更少的资源。
Puppeteer自动化测试的优势
- 高度模拟真实用户行为:Puppeteer能够模拟键盘输入、鼠标点击、表单提交等用户操作,以及更复杂的行为如拖拽、滚动等,使测试更接近用户实际使用情况。
- 无头模式提高测试效率:在无头模式下运行测试,即在后台运行浏览器实例,可以显著提高测试执行的速度,非常适合集成到持续集成/持续部署(CI/CD)流程中。
- 页面渲染和截图:Puppeteer可以渲染并截取页面的屏幕截图或生成PDF,这对于检查页面布局问题和文档生成非常有用。
- 网络请求控制:能够拦截和修改浏览器的网络请求,可以用来模拟不同的网络条件,或者测试应用对失败请求的处理能力。
- 可访问性测试:Puppeteer可以用来检查页面的可访问性,帮助开发者改进网站的无障碍访问能力。
Puppeteer自动化测试的应用场景
- 端到端(E2E)测试:模拟用户在整个应用中的操作流程,从登录到执行具体任务,再到登出,确保整个过程按预期工作。
- 性能测试:通过模拟用户加载页面和执行操作来评估应用的性能,包括加载时间、响应时间等。
- 爬虫:利用Puppeteer遍历网页并提取所需信息,特别是对于JavaScript渲染的内容。
- 自动化截图和PDF生成:自动化生成页面的截图或PDF文档,用于文档、报告或网站内容的备份。
- UI测试:自动化测试用户界面元素是否按照设计显示,包括布局、颜色、字体等。
实战
这里以一个简单的登录页面为例,通过Puppeteer
来实现自动化登录测试。
首先先准备一个登录页面login.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>
</head>
<body>
<h2>Login Page</h2>
<form id="loginForm">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit" id="loginButton">Login</button>
</form>
<div id="message"></div>
<script type="text/javascript">
document.getElementById('loginForm').addEventListener('submit', function(event) {
event.preventDefault(); // 阻止表单默认提交行为
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
if (username === 'admin' && password === '123456') {
document.getElementById('message').textContent = 'Login successful!';
document.getElementById('message').style.color = 'green';
// 实际应用中,这里可以重定向到另一个页面
} else {
document.getElementById('message').textContent = 'Invalid username or password.';
document.getElementById('message').style.color = 'red';
}
});
</script>
</body>
</html>
页面布局如下:
页面在登录成功时,message
元素会显示Login successful!
,并且颜色变成绿色:
页面在登录失败时,比如账号密码不是admin
和123456
时,message
元素会显示Invalid username or password.
,并且颜色变成红色:
在本地先起一个静态服务器,将login.html
放入服务器目录中。
这里需要做的是通过Puppeteer
模拟登录成功和登录失败的情况。 确保你已经安装了Node.js和Puppeteer。如果还没有安装Puppeteer,可以通过运行以下命令来安装:
shell
npm install puppeteer
先贴testLogin.js
代码:
javascript
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: true
});
const page = await browser.newPage();
await page.goto('http://127.0.0.1:8081/login.html');
// 输入用户名和密码
await page.type('#username', 'admin');
await page.type('#password', '123456');
await page.click('#loginButton');
// 验证登录成功
const url = await page.url();
console.log(url); // 根据实际情况判断是否登录成功
await page.waitForSelector('#message', { visible: true });
// 获取消息元素的文本内容
const message = await page.evaluate(() => document.querySelector('#message').textContent);
// 打印消息文本
console.log('Login message:', message);
// 保存登录结果截图到本地
await page.screenshot({ path: 'login.png' });
// 关闭无头浏览器
await browser.close();
})();
puppeteer.launch({ headless: true })
启动了一个无头模式的Chrome实例。page.goto
导航到登录页面,page.type
用于在相应的输入框中输入用户名和密码,page.click
点击登录按钮。page.waitForSelector
等待message元素的展示page.evaluate
用来获取message元素的文本内容,用于后面打印page.screenshot
将登录的结果截图下来,并保存到本地
接下来启动testLogin.js
:
shell
node testLogin.js
可以看到Login successful!
,说明模拟了成功登录
通过输入一个错误的用户名,比如admin1
,并重新启动testLogin.js
,可以看到成功模拟了失败登录
当然也可以关闭无头模式,即设置headless: false
时,Puppeteer会以有界面(GUI)模式启动Chrome或Chromium浏览器。这种模式下,浏览器的窗口会被打开,用户可以看到页面的实时渲染过程,包括模拟用户交互、动画、导航等。
关闭无头模式后,重新启动testLogin.js
, 会自动打开登录页面,自动填入账号和密码,并且点击Login
按钮,以展示登录结果,效果如下:
到此就完成了模拟用户登录的行为,来进行自动化测试。尽管Puppeteer提供了强大的功能,但在实践中也面临一些挑战:
- 测试脚本的维护:随着应用的迭代,测试脚本可能需要频繁更新以适应新的用户界面和功能。
- 复杂场景的模拟:一些复杂的用户交互或边缘情况可能难以准确模拟。
- 资源消耗:虽然无头模式较高效,但在并发执行大量测试脚本时,仍然会占用大量的系统资源。