如何通过Node脚本检测本地Firebase模拟器运行状态并实现单元测试自动连接
检测Firebase模拟器运行状态并自动连接的几种方案
针对你在MacOS上用Node脚本检测Firebase模拟器、自动连接进行单元测试的需求,这里有几个高效的方案:
方案1:用Node内置的net模块直接检测端口连通性
这是最可靠且跨平台的方法,不需要调用系统命令,直接通过网络连接尝试判断端口是否被模拟器占用。Firebase常用模拟器端口:
- Functions: 5000
- Auth: 9099
- Storage: 9199
示例代码:
import { createConnection } from 'net'; function checkEmulatorPort(port, timeout = 1000) { return new Promise((resolve) => { const socket = createConnection(port, 'localhost'); socket.on('connect', () => { socket.end(); resolve(true); // 端口连通,模拟器运行中 }); socket.on('error', () => { resolve(false); // 端口不通,模拟器未运行 }); setTimeout(() => { socket.destroy(); resolve(false); }, timeout); }); } // 使用示例:检测Functions模拟器 async function runChecks() { const functionsRunning = await checkEmulatorPort(5000); const authRunning = await checkEmulatorPort(9099); const storageRunning = await checkEmulatorPort(9199); console.log('Functions模拟器:', functionsRunning ? '运行中' : '未运行'); console.log('Auth模拟器:', authRunning ? '运行中' : '未运行'); console.log('Storage模拟器:', storageRunning ? '运行中' : '未运行'); // 如果所有需要的模拟器都运行,就初始化Admin SDK连接模拟器 if (functionsRunning && authRunning && storageRunning) { // 设置Admin SDK连接模拟器的环境变量 process.env.FIREBASE_AUTH_EMULATOR_HOST = 'localhost:9099'; process.env.FIREBASE_STORAGE_EMULATOR_HOST = 'localhost:9199'; // 初始化Admin SDK import('firebase-admin').then((admin) => { admin.initializeApp(); console.log('已成功连接到所有模拟器'); // 这里开始你的单元测试逻辑 }); } } runChecks();
这个方法的优势是不需要依赖系统命令,纯Node实现,逻辑清晰,容易处理结果。
方案2:优化lsof命令调用,解析输出结果
如果你还是想用lsof,可以调整命令参数让输出更简洁,然后通过Node的exec来解析结果,精准判断是否是Firebase模拟器占用端口:
import { exec } from 'child_process'; function checkPortWithLsof(port) { return new Promise((resolve) => { // 使用-t参数只返回进程ID,无输出则表示端口未被占用 exec(`lsof -ti :${port}`, (error, stdout) => { if (error) { resolve(false); // 命令执行出错,通常是端口未被占用 } else { // 如果stdout有内容,说明端口被占用,进一步判断是否是Firebase进程 if (stdout.trim()) { exec(`ps -p ${stdout.trim()} -o comm=`, (psError, psStdout) => { if (!psError && psStdout.trim().includes('firebase')) { resolve(true); } else { resolve(false); // 端口被其他进程占用 } }); } else { resolve(false); } } }); }); } // 使用示例 checkPortWithLsof(5000).then((isRunning) => { console.log('Functions模拟器:', isRunning ? '运行中' : '未运行'); });
方案3:利用Firebase CLI的emulators:exec自动管理测试环境
其实你不需要手动检测模拟器状态,Firebase CLI提供了firebase emulators:exec命令,可以自动启动所有需要的模拟器,运行你的测试脚本,测试完成后自动关闭模拟器。这是官方推荐的单元测试方式,完全不需要手动处理环境配置。
步骤:
- 在
firebase.json中配置好你的模拟器端口(默认端口也可直接使用) - 在
package.json中添加测试脚本:
{ "scripts": { "test": "firebase emulators:exec \"node your-test-script.js\"" } }
- 运行
npm test,Firebase CLI会自动启动所有启用的模拟器,执行你的测试脚本,测试结束后自动关闭模拟器。
在你的测试脚本中,只需设置Admin SDK连接模拟器的环境变量即可:
import admin from 'firebase-admin'; // 连接到Auth模拟器 process.env.FIREBASE_AUTH_EMULATOR_HOST = 'localhost:9099'; // 连接到Storage模拟器 process.env.FIREBASE_STORAGE_EMULATOR_HOST = 'localhost:9199'; // Functions测试可直接用firebase-functions-test库连接模拟器 admin.initializeApp(); // 这里编写你的单元测试逻辑
这个方案是最省心的,完全自动化,不需要手动处理模拟器的启动/检测/关闭流程。
内容的提问来源于stack exchange,提问作者Matthew Keller
相关产品推荐
相关产品推荐

