【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 });
  });
}

运行结果

相关推荐
frigidom10241 小时前
AutoGen Core Runtime 实战:从消息路由到多智能体协作
人工智能
龙亘川1 小时前
数智防控 全域闭环:智慧安防如何筑牢城市公共安全新底座?
人工智能·信息可视化·开源·智慧城市
AIGS0011 小时前
工艺参数散在Excel和纸质文件里,能不能统一管、随查随用
服务器·数据库·excel·经验沉淀·知识管理·工艺知识·本体语义
武子康1 小时前
第一次用 SGLang:把本地模型接进聊天应用
人工智能·llm·agent
玩美数据-1 小时前
企业级在线调研与数据分析解决方案
大数据·人工智能·数据分析
用户5274675614211 小时前
Agent 跑满一天不等于多一个人:用四个指标算真实产能
人工智能
天远Date Lab1 小时前
零信任架构实战:基于天远行驶OCR证识别构建自动化高并发物流车队准入网关
人工智能·架构·自动化·ocr
厚皮龙1 小时前
CoT Monitoring 与 Activation Monitoring 总结
人工智能
QYR-分析1 小时前
高端精密制造赋能,管材旋锻机行业市场格局、痛点趋势与发展研判
人工智能·制造
Hody911 小时前
【XR硬件介绍】苹果N50智能眼镜技术解读:Vision Pro让位之后,“无屏AI眼镜”凭什么接棒
人工智能·xr