You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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命令,可以自动启动所有需要的模拟器,运行你的测试脚本,测试完成后自动关闭模拟器。这是官方推荐的单元测试方式,完全不需要手动处理环境配置。

步骤:

  1. 在firebase.json中配置好你的模拟器端口(默认端口也可直接使用)
  2. 在package.json中添加测试脚本:
{
  "scripts": {
    "test": "firebase emulators:exec \"node your-test-script.js\""
  }
}
  1. 运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:12:31