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

运行结果

相关推荐
m0_466525292 小时前
数字认证参加第十四届用户体验大会,分享标准建设思路
大数据·人工智能·科技
康实训3 小时前
2026数字化AI智慧实训建设方案
大数据·人工智能·实训室·实训室建设
文人sec3 小时前
玩转excel数据透视表和图表
excel
染指11103 小时前
128.Agent-LangChain核心组件-中间件-调用模型的时候
人工智能·windows·中间件·langchain·agent
布吉岛的石头3 小时前
Java 程序员第 49 阶段5:BERT 预训练目标 MLM+NSP 的工程含义
java·人工智能·深度学习·bert·transformer
玫瑰互动GEO3 小时前
开发者学GEO优化:从算法基础到CoT推理链
大数据·人工智能·ai·geo·ai搜索·geo优化
Zentceh3 小时前
安防监控夜视方案2026:AI全彩+边缘计算+云平台
图像处理·人工智能·科技·计算机视觉·车载系统·无人机·边缘计算
voipmaker3 小时前
AI 赋能安防系统演进:从硬件单品到场景化融合调度架构
人工智能·ai·架构
做cv的小昊3 小时前
【World Model】π0.5:a Vision-Language-Action Model with Open-World Generalization
人工智能·算法·机器学习·大模型·多模态·vla·世界模型
光锥智能4 小时前
具身智能数据,众包时代来了?
人工智能