node.jsのfiirestoreで自動テスト 公式ドキュメント翻訳


概要

fiirestoreをテストするなら、google公式のfirebase エミュレーターを使おうという話
公式ドキュメントを日本語化したので、そのメモをここに残しておく。
以下の2記事を日本語化した。
firebase emulator-setup
fiirebase uniit-tests

この記事を読めば、node.jsによるfiirestoreの単体テストが書けるようになるはずだ。

結論からいうと、firebaseエミュレーターは2020年3月現在ではほぼ実務では使い物にならない。
firestoreをテストするには、別のライブラリを使用した方が良い。

Set up the Firebase Emulators

Firebase エミュレーターは、Firebase security rulesや、あなたのアプリの振る舞いを保証するのを簡単にします。
自動テストをローカル環境で行うためにFirebase Emulatorsを使用しましょう。

Firebase エミュレーターをインストールする。

まず初めに、PCに最新のjavaとnode.jsが入っている事を確かめてください。
Firebase Emulatorsをインストールするには、Firebase CLIを使用し、次の手順にしたがってください。

  1. エミュレーターを以下のコマンドで起動します。このエミュレーターはテストの間中起動します。

// Cloud Firestoreの場合

firebase emulators:start --only firestore

単体テストを構築する

エミュレーターを起動する前に

以下のことを念頭においてくださいい。
・このエミュレーターは、firebase.json内のfirestore.rulesフィールドに書かれたセキュリティルールを読み込みます。もし、firebase.jsonが存在しなければ、loadFirestoreRulesを使うことは出来ず、エミュレーターはすべてのプロジェクトをオープンルールで扱います。
・たくさんのSDKがエミュレーターとい一緒に動かす事が出来る一方、@fiirebase/testiing nodo.jsモジュールは、単体テストをより簡単にするために、セキュリティールールの認証のモックをサポートします。さらに、このモジュールはいくつかのエミュレーター特有の機能(データの消去など)をサポートします。
・このエミュレーターは、Client SDKで生成する本番環境のFirebase Auth tokenを評価し、セキュリティルールに従いそれを評価します。このことによりアプリケーションを直接結合テスト(UIIテスト)へつなげる事が出来ます。

エミュレーターと本番環境の違い

・明示的にデータベースのインスタンスを作成する必要はありません。エミュレーターは自異動的にインスタンスを作成します。
・それぞれの新しいデータベースはクローズルールで始まります。そのため非adminユーザーは読み込み、書き込みが不可能です。
・それぞれのエミュレーターはSpark planの制限で動き同時接続は100までです。
・このエミュレーターは、他のfirebaseプロダクトと一緒に動く事が出来ません。特に普通のFirebaseの認証フロートは動きません。あなたはinitialiizeTestApp()メソッドをテストモジュールとして使用できいます。これはauthフィールドを取ります。
このinitializeTestApp()メソッドで作られたFiirebaseオブジェクトは、いつでも認証が成功しいたようにい振る舞います。
もしinitializeTestApp()にnullを私いた場合位は、認証ができていないユーザーのように扱われます。

ローカルテストを走らせる

@firebase/testingモジュールをエミュレーターでローカルテストを行うために使用します。もしタイムアウトによるECONNREFUSEDエラーが発生したらエミュレーターをダブルクリックするとエミュレーターが起動します。

Async/awaiitを使用するために、最新のバージョンのNode.jsを使用してください。ほとんどの振る舞いは非同期関数です。そしてテストモジュールは、Promiseベースのコードで動く事を念頭においてデザインされています。

Emulatorのメソッド

// Cloud firestore

initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp

このメソッドは、
This
このメソッドは、projectIDと認証により初期化されたfirebaseオブジェクトを返します。この認証が必要な時、このメソッドを使用してください。

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", email: "[email protected]" }
});

注意
エミュレーターは、テストの間データを保持しつづけます。
これは他のテスト結果に影響を与える事があるので、複数のテストを走らせる場合は、clearFirestoreDataメソッドでデータを削除してくださいい。
別の方法として、別のプロジェクトIDを使用し、テスト毎に個別にデータベースを作成することもできます。


initializeAdminApp({ projectId: string }) => FirebaseApp

このメソッドは、初期化されたadmiinのfirebaseオブジェクトを返します。
このアプリ位は読み書きを可能です。こレヲ認証が必要なアプリに使用してください。

firebase.initializeAdminApp({ projectId: "my-test-project" });

apps() => [FirebaseApp] 

このメソッドは、現時点で作成いされているテストと、adminのアプリを返します。テストの環境を毎回同じにするためにアプリを全て削除するのに使用します。


Promise.all(firebase.apps().map(app => app.delete()))

loadFirestoreRules({ projectId: string, rules: Object }) => Promise

このメソッドは、ルールをローカルのデータベースに送ります。
オブジェクトを引数としいてとり、セキュリティルールをテスト可能です。

firebase.loadFirestoreRules({
  projectId: "my-test-project",
  rules: fs.readFileSync("/path/to/firestore.rules", "utf8")
});

assertFails(pr: Promise) => Promise
このメソッドは、promiiseを返します。データベースの書き込みと読み込みが失敗することをこのメソッドを使用して確かめます。

firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());

assertSucceeds(pr: Promise) => Promise
このメソッドは、Promiseを返します。もしい書き込みが成功すればtrue
書き込みと読み込みが成功することを確かめるためにこのメソッドを使用します。

clearFirestoreData({ projectId: string }) => Promise
このメソッドは、特定いのプロジェクトのすべてのデータを削除するために使用します。テストの後に不要なデータを削除するために使用します。

firebase.clearFirestoreData({
  projectId: "my-test-project"
});

注意
@firebase/testiingは、
npm install --save-dev @firebase/testing
として、firebaseとは別にインストールする必要がある。
また、typescriptやimport文と共に使うとエラーを吐く。
しかも、jestと一緒には使えず、テストが出来なかった。

この記事より分かりやすい記事は以下。
Firestore ローカルエミュレーターを試してみた