第二章:测试环境搭建——Node.js 与 npm 环境配置、Jest 与 Playwright 框架安装、项目初始化与目录结构设计
说实话,很多同学刚开始学前端测试,第一个拦路虎往往不是测试框架本身,而是环境没搭好。我见过太多人花了一整天装依赖,结果跑起来全是红字报错。嗯,这一章我们就来把地基打牢。
2.1 Node.js 与 npm:测试的基石
为什么一定要 Node.js?因为 Jest 和 Playwright 都跑在 Node 环境上。你想想看,没有 Node,这些工具连启动都做不到。
2.1.1 安装 Node.js
我个人习惯用 nvm(Node Version Manager)来管理 Node 版本。为什么?因为不同项目可能依赖不同版本的 Node,手动切换太痛苦了。
安装 nvm(以 macOS/Linux 为例):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
装完之后,重启终端或者执行 source ~/.bashrc。然后安装 Node.js 的 LTS 版本:
nvm install --lts
nvm use --lts
验证是否装好:
node -v # 比如 v20.11.0
npm -v # 比如 10.2.4
2.1.2 npm 的配置与加速
npm 默认源在国外,下载速度你懂的。我曾经在客户现场演示搭建环境,结果等了五分钟还在转圈……场面一度非常尴尬。
所以,第一件事就是换源:
npm config set registry https://registry.npmmirror.com
或者用 cnpm:
npm install -g cnpm --registry=https://registry.npmmirror.com
我个人更推荐直接换 registry,因为这样所有 npm 命令都自动走国内镜像,不用额外记 cnpm 的命令。
2.2 安装 Jest 与 Playwright
环境搭好了,接下来装测试框架。这里我选 Jest 做单元测试,Playwright 做端到端测试。为什么是这两个组合?
- Jest:零配置、速度快、生态好。做单元测试和组件测试,它是最省心的选择。
- Playwright:微软出品,支持多浏览器、多语言,API 设计得很现代。相比 Cypress,它更灵活,而且能测 Electron 应用。
2.2.1 初始化项目
先创建一个项目目录:
mkdir frontend-testing-course
cd frontend-testing-course
npm init -y
npm init -y 会生成一个 package.json 文件。我建议你打开看看,里面记录了项目的元信息和依赖列表。嗯,这个文件后面我们会频繁修改。
2.2.2 安装 Jest
npm install --save-dev jest
装完之后,在 package.json 里加一条脚本:
"scripts": {
"test": "jest"
}
验证安装:
npx jest --version
# 输出:29.7.0(版本号可能不同)
__tests__ 目录下的文件,以及文件名包含 .test. 或 .spec. 的文件。这个规则后面会用到。
2.2.3 安装 Playwright
npm install --save-dev @playwright/test
装完之后,还需要安装浏览器:
npx playwright install
这个命令会下载 Chromium、Firefox 和 WebKit 三个浏览器。我第一次跑的时候等了快十分钟,因为要下载几百兆的浏览器二进制文件。别急,这是正常的。
验证安装:
npx playwright --version
# 输出:1.41.0
npx playwright install,结果测试全部报错「浏览器未找到」。所以,记得把这一步加到 CI 脚本里。
2.3 项目初始化与目录结构设计
环境装好了,接下来是目录结构。很多新手喜欢把所有文件堆在根目录,结果项目一大了就找不到北。我建议从一开始就规划好。
2.3.1 推荐的目录结构
frontend-testing-course/
├── src/ # 源代码
│ ├── components/ # 组件
│ ├── utils/ # 工具函数
│ └── pages/ # 页面
├── tests/ # 测试代码
│ ├── unit/ # 单元测试
│ │ ├── components/ # 组件测试
│ │ └── utils/ # 工具函数测试
│ ├── e2e/ # 端到端测试
│ │ ├── specs/ # 测试用例
│ │ └── fixtures/ # 测试数据
│ └── setup/ # 测试配置
├── playwright.config.js # Playwright 配置
├── jest.config.js # Jest 配置
├── package.json
└── README.md
为什么这样分?
- src/ 和 tests/ 分开:源代码和测试代码混在一起,容易混淆。分开后,发布时可以直接排除 tests/ 目录。
- unit/ 和 e2e/ 分开:单元测试跑得快,端到端测试跑得慢。分开后,你可以只跑单元测试做快速反馈。
- setup/ 目录:放一些测试前的准备工作,比如 mock 数据、全局配置。我习惯把
jest.setup.js和playwright.setup.js放这里。
2.3.2 配置 Jest
在项目根目录创建 jest.config.js:
module.exports = {
testEnvironment: 'jsdom',
roots: ['<rootDir>/tests/unit'],
testMatch: ['**/*.test.js'],
setupFilesAfterSetup: ['<rootDir>/tests/setup/jest.setup.js'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
}
};
这里我解释几个关键配置:
- testEnvironment: 'jsdom':模拟浏览器环境,这样你可以在 Node 里测试 DOM 操作。
- roots:告诉 Jest 去哪里找测试文件。我指定了
tests/unit,这样它就不会去tests/e2e里找单元测试了。 - moduleNameMapper:配置路径别名。比如
@/components/Button会自动映射到src/components/Button。这个在大型项目里特别有用。
2.3.3 配置 Playwright
创建 playwright.config.js:
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests/e2e',
timeout: 30000,
retries: 2,
use: {
baseURL: 'http://localhost:3000',
headless: true,
screenshot: 'only-on-failure',
video: 'retain-on-failure'
},
projects: [
{
name: 'chromium',
use: { browserName: 'chromium' }
},
{
name: 'firefox',
use: { browserName: 'firefox' }
}
]
});
说几个我踩过的坑:
- timeout 设成 30000:默认是 30 秒,但有些页面加载慢,我建议根据实际情况调整。我曾经设成 10 秒,结果测试老是超时,排查了半天才发现是网络问题。
- retries: 2:端到端测试不稳定,偶尔会因为网络波动失败。重试两次能大幅降低误报率。
- screenshot 和 video:失败时截图和录视频,方便排查问题。这个在 CI 上特别有用。
2.3.4 创建第一个测试文件
在 tests/unit/utils 下创建 math.test.js:
const { add } = require('../../src/utils/math');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
然后在 src/utils/math.js 里实现:
function add(a, b) {
return a + b;
}
module.exports = { add };
跑一下测试:
npm test
看到绿色的 PASS 了吗?嗯,这就是你搭建的第一个测试环境。
package.json 里加一条 "test:watch": "jest --watch" 脚本。这样改完代码,测试会自动重新运行,开发体验好很多。
2.4 本章小结
这一章我们做了三件事:
- 装了 Node.js 和 npm,配了国内镜像源
- 装了 Jest 和 Playwright,验证了安装成功
- 设计了项目目录结构,配置了测试框架
说实话,环境搭建是最枯燥的部分,但也是最重要的。我见过太多人因为环境问题卡住,最后放弃了学习测试。别急,慢慢来,把每一步走稳了,后面写测试用例会顺畅很多。
下一章,我们会正式进入 Jest 的世界,从最简单的断言开始,一步步写出高质量的单元测试。