【Playwright】 自动化测试之参数化登录(Excel/CSV 数据源)

📌 背景

在日常测试中,我们经常需要验证多个账号是否能正常登录系统。手动一个个输入不仅效率低,还容易出错。

本文将用 Playwright 配合 Excel/CSV 数据文件,实现自动化批量登录测试,并检查登录是否成功

🧩 方案选择

方案一:直接读取 .xlsx 文件(推荐)

需要:安装 xlsx 库(npm install xlsx)。

代码最简洁:用列名取值,不怕列顺序变化。

方案二:读取 .csv 文件(轻量)

优点:无需额外依赖,Node.js 原生 fs 模块即可。

需要:先用 Excel 将文件另存为 "CSV UTF-8 (逗号分隔)"。

注意:确保 CSV 是真正的逗号分隔,且编码为 UTF-8。

🚀 方案一:读取 .xlsx(列名版)

  1. 安装依赖
bash 复制代码
2026-06-16 14:39 with jianju in Test/playwright_tests/gxnydsj on  master [?] is 📦 v1.0.0 via ⬢ v22.22.0 
➜ npm install xlsx --save-dev

added 9 packages in 2s
  1. 代码
bash 复制代码
import { test, expect } from '@playwright/test';
import XLSX from 'xlsx';

//=====从 Excel 文件(/Users/jianju/Downloads/区域人员管理列表.xlsx)里,
// 把"用户名"和"密码"两列的数据提取出来,存成一个列表(数组),方便后面逐个登录。
// 1. 读取文件,并把所有的内容,都存在"workbook"里面
const workbook = XLSX.readFile('/Users/Downloads/区域人员管理列表.xlsx');
// 2.一个 Excel 可能有多个工作表(Sheet),这个代码取第一个工作表(Sheet0),存到 sheet 里。
const sheet = workbook.Sheets[workbook.SheetNames[0]];
// 3. 转换成一张"大表格"(二维数组)。不要把第一行当作列名,而是把每一行都当成一个普通数组,
const data = XLSX.utils.sheet_to_json(sheet, { header: 1 });

// 4. 从第二行开始提取用户名(第4列,索引3)和密码(第5列,索引4)
const users = data
  .slice(1)                     // 跳过第一行,即跳过表头
  .map(row => ({
    //第4个元素(索引3) → 因为索引从0开始,所以 row[3] 就是"用户名"列。
    //|| '' 表示如果这一格是空的,就当作空字符串。
    //.toString() 保证它一定是文本。
    //.replace(/\0/g, '') 是去掉一些看不见的"空字符"(之前数据库报错就是因为这个),就像把杂物剔除。
    // .trim() 去掉首尾多余的空格。
    u: (row[3] || '').toString().replace(/\0/g, '').trim(),  
    p: (row[4] || '').toString().replace(/\0/g, '').trim()
  }))
  .filter(item => item.u && item.p); // 过滤空值

for (const { u, p } of users) {
  test(`登录 ${u}`, async ({ page }) => {
    await page.goto('http://1.1.1.1/test/home');
    // 如果不需要点击菜单,可以注释掉下面这行(根据您手动测试的结果)
    await page.getByRole('listitem').filter({ hasText: '农用薄膜残留监测' }).click();
    await page.getByRole('textbox', { name: '用户名' }).fill(u);
    await page.getByRole('textbox', { name: '密码' }).fill(p);
    await page.getByRole('button', { name: '登 录' }).click();
    await expect(page.getByRole('heading', { name: '农用薄膜调查监测' })).toBeVisible({
      timeout: 10000
    });
  });
}

📄 方案二:读取 .csv

bash 复制代码
import fs from 'fs';      //专门读取csv文件
import { test, expect } from '@playwright/test';
//读取文件内容,并通过换行符,切成一行一行,放在lines里面
const lines = fs.readFileSync('/Users/Downloads/区域人员管理列表.csv', 'utf-8').split('\n');
//从第 2 行开始,一直循环到最后一行"。(i从0开始,0是第一行)
for (let i = 1; i < lines.length; i++) {
  //比如某一行是 "测试,北海,测试账号,shiboom29,shiboom29,管理员",用 split(',') 切成 ["测试", "北海", "测试账号", "shiboom29", "shiboom29", "管理员"]。
  //.map(s => s.trim()) 是把每个字段前后的空格都去掉(比如有时候 Excel 导出会在字段末尾带空格,去掉更干净)。
  //处理完的结果存在 cols 里,这就是当前用户的各个字段。
  const cols = lines[i].split(',').map(s => s.trim());  

  const u = cols[3];  //第 4 列是"用户名",在数组里索引是 3
  const p = cols[4];
  if (!u || !p) continue;  //如果用户名或密码是空的,就跳过这一行

  test(`登录 ${u}`, async ({ page }) => {
    await page.goto('http://1.1.1.1/test/home');
    await page.getByRole('listitem').filter({ hasText: '农用薄膜残留监测' }).click();
    await page.getByRole('textbox', { name: '用户名' }).fill(u);
    await page.getByRole('textbox', { name: '密码' }).fill(p);
    await page.getByRole('button', { name: '登 录' }).click();
    await expect(page.getByRole('heading', { name: '农用薄膜调查监测' })).toBeVisible({ timeout: 10000 });
  });
}

运行结果

相关推荐
2501_9381400739 分钟前
做内容很省心,2026好用AI笔记,支持抖音小红书视频无水印保存
人工智能
sell-cloud3 小时前
Prompt Engineering要凉了?Fable 5.5能“猜“意图,但银行正在封杀AI Agent——企业AI的真正护城河是什么
人工智能·prompt
Navicat中国5 小时前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI5 小时前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区5 小时前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris7 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy8 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V8 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI8 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技8 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人