无头浏览器Puppeteer可以模拟真实用户在Chrome浏览器中的操作行为,针对XML文件上传这类需要前端交互的测试场景,能够完整复现选择文件、提交表单、等待响应的全流程,避免手动测试的重复劳动和人为误差。

环境准备与基础配置
首先需要确保本地已安装Node.js环境,然后通过npm安装Puppeteer依赖:
npm install puppeteer --save-dev
安装完成后,我们可以先编写一个基础的Puppeteer启动脚本,验证环境是否正常工作:
const puppeteer = require('puppeteer');
async function launchBrowser() {
// 启动无头浏览器,设置headless为false可看到可视化操作过程,调试完成后改为true
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1280, height: 720 }
});
const page = await browser.newPage();
return { browser, page };
}
XML上传的自动化实现步骤
1. 定位上传控件并准备测试文件
XML上传通常需要通过<input type="file">控件实现,我们首先需要在测试页面中定位到该控件,同时准备一个合法的XML测试文件,放在项目指定目录下。
假设测试页面的上传控件代码如下:
<form id="xmlUploadForm" action="/api/upload-xml" method="post" enctype="multipart/form-data"> <input type="file" id="xmlFileInput" accept=".xml" /> <button type="submit" id="submitBtn">上传XML</button> </form>
我们可以准备一个简单的测试XML文件test_data.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <user> <id>1001</id> <name>测试用户</name> </user>
2. 模拟文件选择与表单提交
Puppeteer提供了uploadFile方法,可以直接向文件上传控件注入本地文件路径,无需模拟点击文件选择弹窗的复杂操作:
const path = require('path');
async function uploadXmlTest() {
const { browser, page } = await launchBrowser();
// 访问测试页面,替换为实际的页面地址
await page.goto('http://127.0.0.1:3000/upload-page');
// 等待上传控件加载完成
await page.waitForSelector('#xmlFileInput');
// 获取测试XML文件的绝对路径
const xmlFilePath = path.resolve(__dirname, 'test_data.xml');
// 向文件上传控件注入文件
const fileInput = await page.$('#xmlFileInput');
await fileInput.uploadFile(xmlFilePath);
// 监听接口响应,等待上传结果
const [response] = await Promise.all([
page.waitForResponse(res => res.url().includes('/api/upload-xml') && res.status() === 200),
// 点击提交按钮
page.click('#submitBtn')
]);
// 解析响应结果
const result = await response.json();
console.log('上传结果:', result);
await browser.close();
}
uploadXmlTest().catch(console.error);
3. 验证上传结果
上传完成后,我们需要验证后端返回的结果是否符合预期,比如是否返回上传成功标识、文件解析后的内容是否正确:
async function assertUploadResult(response) {
const result = await response.json();
// 验证上传状态
if (result.code !== 0) {
throw new Error(`上传失败,错误信息:${result.message}`);
}
// 验证解析后的内容是否正确
if (result.data.user_id !== 1001) {
throw new Error('XML解析结果不符合预期');
}
console.log('XML上传测试通过');
}
异常场景测试覆盖
除了正常上传场景,我们还需要覆盖常见的异常情况,保证上传功能的健壮性:
- 上传非XML格式文件,验证后端是否返回格式错误提示
- 上传超大尺寸XML文件,验证大小限制是否生效
- 上传内容不符合Schema规范的XML文件,验证解析校验逻辑
以下是测试非XML文件上传的示例代码:
async function testInvalidFileUpload() {
const { browser, page } = await launchBrowser();
await page.goto('http://127.0.0.1:3000/upload-page');
await page.waitForSelector('#xmlFileInput');
// 准备一个txt文件模拟非法格式
const txtFilePath = path.resolve(__dirname, 'invalid.txt');
const fileInput = await page.$('#xmlFileInput');
await fileInput.uploadFile(txtFilePath);
const [response] = await Promise.all([
page.waitForResponse(res => res.url().includes('/api/upload-xml')),
page.click('#submitBtn')
]);
const result = await response.json();
if (result.code === 0) {
throw new Error('非法文件上传未拦截,测试失败');
}
console.log('非法文件上传拦截测试通过');
await browser.close();
}
测试执行与优化建议
可以将上述测试用例整合到测试框架中,比如Jest或者Mocha,实现批量执行和结果报告生成。同时建议在测试完成后清理测试产生的临时数据,避免影响后续测试。如果需要模拟多文件上传,只需要将多个文件路径传入uploadFile方法即可,参数支持数组形式传入多个文件路径。