如何基于Firebase模拟器搭建含Firestore、Auth、Functions的集成测试?
搭建覆盖Firebase Auth、Firestore、Cloud Functions及REST API的端到端自动化测试项目
完全可以搭建符合你需求的测试项目,下面是一步步的实现方案,全程自动化无需手动操作:
一、先把环境搭好
- 安装最新版
firebase-tools:npm install -g firebase-tools - 若未初始化Firebase项目,先执行
firebase init,勾选Auth、Firestore、Functions模块 - 安装测试依赖:
npm install --save-dev mocha chai firebase-admin firebase-functions-test axios(用mocha运行测试,chai做断言验证,axios调用API)
二、配置模拟器自动清空数据
- 生成模拟器配置:
firebase init emulators,勾选Auth、Firestore、Functions,设置端口(例:Auth用9099,Firestore用8080,Functions用5001) - 打开
firebase.json,给每个模拟器加上"clearData": true,确保每次启动模拟器都会清空历史测试数据:
{ "emulators": { "auth": { "port": 9099, "clearData": true }, "firestore": { "port": 8080, "clearData": true }, "functions": { "port": 5001, "clearData": true }, "ui": { "enabled": true } } }
三、编写自动化测试脚本(以Mocha为例)
在项目根目录创建test/e2e.test.js,按你的测试流程逐步实现:
1. 初始化测试环境
const admin = require('firebase-admin'); const axios = require('axios'); const { expect } = require('chai'); // 连接本地模拟器,避免操作生产环境数据 admin.initializeApp({ credential: admin.credential.applicationDefault(), databaseURL: 'http://localhost:8080', authDomain: 'localhost:9099' }); const auth = admin.auth(); const firestore = admin.firestore(); // 强制指向Firestore模拟器地址 firestore.settings({ host: 'localhost:8080', ssl: false });
2. 实现完整测试流程
describe('Firebase端到端测试', () => { let testUser; let idToken; // 每个测试完成后清理数据,避免污染后续测试 afterEach(async () => { if (testUser) { await auth.deleteUser(testUser.uid); await firestore.collection('users').doc(testUser.uid).delete(); } }); it('注册用户,验证Cloud Functions是否正确更新users集合', async () => { // 创建测试用户Jake Williams testUser = await auth.createUser({ email: 'jake.williams@test.com', password: 'Test123!', displayName: 'Jake Williams' }); // 等待Cloud Functions异步执行完成(根据函数复杂度调整延迟时间) await new Promise(resolve => setTimeout(resolve, 2000)); // 验证users集合的文档是否正确创建 const userDoc = await firestore.collection('users').doc(testUser.uid).get(); expect(userDoc.exists).to.be.true; expect(userDoc.data().displayName).to.equal('Jake Williams'); expect(userDoc.data().email).to.equal('jake.williams@test.com'); }); it('登录后调用REST API,验证Firestore数据变更', async () => { // 先创建测试用户 testUser = await auth.createUser({ email: 'jake.williams@test.com', password: 'Test123!', displayName: 'Jake Williams' }); // 调用Auth模拟器接口获取客户端ID Token,模拟真实用户登录流程 const tokenRes = await axios.post( 'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=test', { email: 'jake.williams@test.com', password: 'Test123!', returnSecureToken: true } ); idToken = tokenRes.data.idToken; // 调用你的类REST API(假设部署在Functions模拟器,路径为/api/updateUser) await axios.post( 'http://localhost:5001/你的项目ID/us-central1/api/updateUser', { displayName: 'Jake W.' }, { headers: { Authorization: `Bearer ${idToken}` } } ); // 验证Firestore数据是否已更新 const updatedDoc = await firestore.collection('users').doc(testUser.uid).get(); expect(updatedDoc.data().displayName).to.equal('Jake W.'); }); });
3. 配置测试启动脚本
在package.json中添加测试命令:
"scripts": { "test": "mocha test/e2e.test.js --exit" }
四、执行完整测试流程
- 第一个终端启动模拟器:
firebase emulators:start(启动时会自动清空所有历史数据) - 第二个终端运行测试:
npm test - 每个测试完成后,
afterEach钩子会自动清理当前测试的用户和Firestore数据,确保后续测试在干净环境中执行
关键注意事项
- 异步等待:Cloud Functions是异步触发的,测试时必须添加延迟或监听文档变化,避免出现函数未执行完就验证的情况
- 模拟器地址:所有Admin SDK和API调用必须指向本地模拟器,绝对不能连接生产环境
- ID Token获取:使用Auth模拟器的REST接口获取token,不要用Admin SDK生成,更贴近真实用户的权限场景
- 数据隔离:每个测试都要清理数据,避免不同测试之间互相干扰
内容的提问来源于stack exchange,提问作者amitdigga
相关产品推荐
相关产品推荐

