Daiki Urata (@daio7nohe)
合計1億件以上の個人情報がFirebaseの脆弱性によって公開状態に (Gigazineより)
↓
「Firebaseの脆弱性」ではなく、開発者がSecurity Rulesをしっかり設定していなかったために起こった出来事だった模様
@firebase/testing
)のみサポートわざわざテスト用Firebaseプロジェクトを用意せずにCIでテスト自動化できる !
Emulatorインストール、起動
$ firebase setup:emulators:firestore
$ firebase serve --only firestore
import * as firebase from "@firebase/testing";
firebase.initializeTestApp({
projectId: "my-test-project",
auth: { uid: "alice", email: "alice@example.com" }
});
どんなものか触ってみたい方は
https://github.com/firebase/quickstart-nodejs
に公式サンプルがあります。
exports.helloWorld = functions.https
.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
$ firebase serve --only functions
exports.createUsername = functions.firestore
.document("user/{userId}")
.onCreate((snap, context) => {
const newValue = snap.data();
const username = newValue.email.split("@")[0];
return snap.ref.set({ username }, { merge: true });
});
$ firebase functions:shell
firebase > createUsername({ email: "7noeh@example.com" })
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: Execution took 1522 ms, user function completed successfully
firebase-functions-test
// config値
{
"someservice": {
"key":"THE API KEY"
}
}
// functionsのコード
const functions = require('firebase-functions');
const key = functions.config().someservice.key;
// config値のモック
const test = require("firebase-functions-test")();
test.mockConfig({ someservice: { key: '23wr42ewr34' }});
Firestore Functions (non-Http Functions)のテスト
const test = require("firebase-functions-test")();
const myFunctions = require('../index.js');
// Make snapshot
const snap = test.firestore.makeDocumentSnapshot({foo: 'bar'}, 'document/path');
// Call wrapped function with the snapshot
const wrapped = test.wrap(myFunctions.makeUppercase);
wrapped(snap);
Http Functionの例
exports.helloWorld = functions.https
.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
Http Functionのテストコード例
import myFunctions from "../functions/index";
// Http Functions Testing
describe("helloworld", () => {
test("should return message", () => {
const req = { query: { text: "input" } };
const res = {
send: result => {
expect(result).toBe("Hello from Firebase!");
}
};
myFunctions.helloWorld(req, res);
});
});
Firestore Functionの例
exports.createUsername = functions.firestore
.document("user/{userId}")
.onCreate((snap, context) => {
const newValue = snap.data();
const username = newValue.email.split("@")[0];
return snap.ref.set({ username }, { merge: true });
});
Firestore Functionsのテストコード例
(offlineモード)
import myFunctions from "../functions/index";
import sinon from "sinon";
const fft = require("firebase-functions-test")();
// Firestore Functions Testing
describe("createUsername", () => {
test("shoud create username from email", () => {
const setStub = sinon.stub();
const snap = {
data: () => ({
email: "7nohe@example.com"
}),
ref: {
set: setStub
}
};
setStub.withArgs({ username: "7nohe" }, { merge: true }).returns(true);
const wrapped = fft.wrap(myFunctions.createUsername);
expect(wrapped(snap, { params: { userId: "user-id-12345" } })).toBe(true);
});
});
今の所、こうするしかないと思う
Firestore emulatorが使えるといい
DBリセットとかは gcloud beta firestore import
コマンドでテストデータをインポートする?
https://firebase.google.com/docs/test-lab/
*Android/iOSのみ