Firebase Local Emulator Suite 可讓您更輕鬆地完整驗證應用程式的 特徵和行為這部 很適合驗證 Firebase Security Rules 設定。使用 Firebase 模擬器 在本機環境中執行及自動化單元測試。在 Cloud 控制台中 這份文件應該可以協助你為應用程式建構及自動執行單元測試 驗證 Rules。
如果尚未設定 Firebase Emulator,請先進行設定。
執行模擬器之前
開始使用模擬器前,請注意下列事項:
- 模擬器一開始會載入
firestore.rules
中指定的規則 或「storage.rules」欄位的值firebase.json
。如果檔案沒有 且未使用loadFirestoreRules
或「loadStorageRules」種方式 如下所述,模擬器會將所有專案視為有開放規則。 - 雖然
大部分 Firebase SDK
只能直接和模擬器搭配使用,只有
@firebase/rules-unit-testing
程式庫支援 模擬安全性規則中的auth
可簡化單元測試。此外, 程式庫支援幾項模擬器專屬功能,例如清除所有資料 說明。 - 模擬器也會接受你提供的正式版 Firebase 驗證權杖 並透過用戶端 SDK 據此評估規則 即可將您的應用程式直接傳送至模擬器,並進行手動測試。
資料庫模擬器與正式環境之間的差異
- 您不必明確建立資料庫執行個體。模擬器會自動建立任何可存取的資料庫例項。
- 每個新資料庫都會啟用封閉規則,因此非管理員使用者無法讀取或寫入資料。
- 每個模擬的資料庫都會套用 Spark 方案 上限和配額 (最值得注意的是,這個上限是每個執行個體將並行數量限制為 100 個 連線)。
- 任何資料庫都會接受
"owner"
字串做為管理員驗證權杖。 - 模擬器目前無法與其他 Firebase 互動
很少直接解答該如何打造產品值得注意的是,一般 Firebase 驗證流程無法運作。
您可以改為在
rules-unit-testing
中使用initializeTestApp()
方法 會採用auth
欄位透過此參數建立的 Firebase 物件 方法就如同 提供的實體如果傳入null
,系統會視為 未經驗證的使用者 (例如auth != null
規則將失敗)。
與 Realtime Database 模擬器互動
實際工作環境的 Firebase Realtime Database 執行個體可在以下的子網域存取:
firebaseio.com
,而您可以按照以下方式存取 REST API:
https://<database_name>.firebaseio.com/path/to/my/data.json
模擬器會在本機執行,並可從 localhost:9000
取得。如要與特定資料庫執行個體互動,您必須使用 ns
查詢參數指定資料庫名稱。
http://localhost:9000/path/to/my/data.json?ns=<database_name>
使用第 9 版 JavaScript SDK 執行本機單元測試
Firebase 發布了同時包含兩個版本的安全性規則單元測試程式庫 9 JavaScript SDK 和第 8 版 SDK。程式庫 API 主要 也不一樣建議您使用更精簡的 v9 測試程式庫 連線至模擬器所需的設定較少,因此可以安全避免意外 控管正式環境資源的方式為了兼顧回溯相容性,我們會持續 可用的 v8 測試程式庫。
使用 @firebase/rules-unit-testing
模組與模擬器互動
執行在本機的容器如果出現逾時或 ECONNREFUSED
錯誤,請仔細檢查模擬器是否確實正在執行。
強烈建議您使用新版 Node.js,以便使用
async/await
標記法。您想要測試的所有行為
涉及非同步函式,而測試模組的設計宗旨是讓
以 Promise 為基礎的程式碼。
v9 Rules 單元測試程式庫一律會感知模擬器, 您會很熟悉生產資源
您可使用 v9 模組匯入陳述式匯入程式庫。例如:
import {
assertFails,
assertSucceeds,
initializeTestEnvironment
} from "@firebase/rules-unit-testing"
// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.
匯入後,實作單元測試涉及:
- 透過對
initializeTestEnvironment
的呼叫,建立及設定RulesTestEnvironment
。 - 以便利的方式設定測試資料,而不觸發 Rules
方法可讓您暫時略過
RulesTestEnvironment.withSecurityRulesDisabled
。 - 設定測試套件,並在掛鉤前後進行個別測試
清除測試資料和環境 (例如
RulesTestEnvironment.cleanup()
) 或RulesTestEnvironment.clearFirestore()
。 - 使用
「
RulesTestEnvironment.authenticatedContext
」和RulesTestEnvironment.unauthenticatedContext
。
常用方法和公用程式函式
另請參閱 使用模組 API 的特定模擬器測試方法。
initializeTestEnvironment() => RulesTestEnvironment
這個函式會初始化規則單元測試的測試環境。呼叫此項目 函式,用於測試設定。成功執行需要模擬器必須 備用資源
此函式接受選用物件定義 TestEnvironmentConfig
,
包含專案 ID 和模擬器配置設定。
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
這個方法會建立 RulesTestContext
,其運作方式類似於經過驗證的
Authentication 位使用者。透過傳回的結構定義建立的要求會有模擬畫面
已附加 Authentication 個權杖。您可以選擇傳遞定義自訂宣告或覆寫 Authentication 權杖酬載的物件。
在測試中使用傳回的測試情境物件存取任何模擬器
設定的執行個體,包括使用 initializeTestEnvironment
設定的執行個體。
// Assuming a Firestore app and the Firestore emulator for this example import { setDoc } from "firebase/firestore"; const alice = testEnv.authenticatedContext("alice", { … }); // Use the Firestore instance associated with this context await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
RulesTestEnvironment.unauthenticatedContext() => RulesTestContext
這個方法會建立 RulesTestContext
,運作方式就像用戶端
未透過 Authentication 登入。透過傳回的結構定義建立的要求不會
已附加 Firebase 驗證權杖。
在測試中使用傳回的測試情境物件存取任何模擬器
設定的執行個體,包括使用 initializeTestEnvironment
設定的執行個體。
// Assuming a Cloud Storage app and the Storage emulator for this example import { getStorage, ref, deleteObject } from "firebase/storage"; const alice = testEnv.unauthenticatedContext(); // Use the Cloud Storage instance associated with this context const desertRef = ref(alice.storage(), 'images/desert.jpg'); await assertSucceeds(deleteObject(desertRef));
RulesTestEnvironment.withSecurityRulesDisabled()
利用情境模擬安全性規則,執行測試設定函式 已停用。
這個方法會採用回呼函式,該函式會採用 Security-Rules-bypassing 內容並傳回 Promise。承諾解析/拒絕後,系統就會銷毀這個內容。
RulesTestEnvironment.cleanup()
這個方法會刪除在測試環境中建立的所有 RulesTestContexts
,並
這會清除基礎資源,以便順暢結束作業。
這個方法不會以任何方式變更模擬器的狀態。重設資料的方式 請使用應用程式模擬器專屬的清除資料方法,才能進行測試。
assertSucceeds(pr: Promise<any>)) => Promise<any>
這是測試案例公用程式函式。
這個函式會宣告提供的 Promise 包裝模擬器作業 會在沒有違反安全性規則的情況下解決。
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
這是測試案例公用程式。
這個函式會宣告提供的 Promise 包裝模擬器作業 就會遭到拒絕,並顯示安全性規則。
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Android Emulator 專用方法
另請參閱 常見的測試方法和模組函式使用模組化 API 的公用程式函式。
Cloud Firestore
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
這個方法會清除屬於
為 Firestore 模擬器設定的 projectId
。
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
這個方法會取得此測試結構定義的 Firestore 執行個體。傳回的 Firebase JS 用戶端 SDK 執行個體可與用戶端 SDK API (第 9 版模組) 搭配使用 或 v9 Compat)。
Realtime Database
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
這個方法會清除屬於Realtime Database
為 Realtime Database 模擬器設定的 projectId
。
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
取得這個測試結構定義的 Realtime Database 例項。傳回的 Firebase JS Client SDK 例項可搭配用戶端 SDK API (模組化或命名空間,版本 9 以上) 使用。此方法會接受即時資料庫例項的網址。如果有指定,系統會傳回模擬版本 包含擷取自網址之參數的命名空間
Cloud Storage
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
這個方法會清除
已為 Cloud Storage 模擬器設定 projectId
。
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
這個方法會傳回設定以連線至模擬器的 Storage 執行個體。
此方法會接受 gs://
至 Firebase Storage Bucket 的網址,以便進行測試。如果
會回傳 Cloud Storage 執行個體,該值區名稱的模擬版本。
使用 v8 JavaScript SDK 執行本機單元測試
選取產品即可查看 Firebase Test SDK 用於介面的方法 實際操作
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
這個方法會傳回與專案對應的已初始化 Firebase 應用程式 選項中指定的 ID 和驗證變數。使用此功能建立應用程式 以特定使用者的身分通過驗證,以便用於測試。
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
這個方法會傳回已初始化的管理員 Firebase 應用程式。執行讀取和寫入作業時,這個應用程式會略過安全性規則。使用此功能建立應用程式 須以管理員的身分通過驗證,才能設定測試狀態。
firebase.initializeAdminApp({ projectId: "my-test-project" });
apps() => [FirebaseApp]
這個方法會傳回目前已初始化的所有測試和管理應用程式。您可以使用這項功能來清除測試期間或測試後的應用程式。
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
這個方法會傳回在輸入成功時遭到拒絕的承諾,或 就會成功。使用此方法斷言資料庫是否讀取或 寫入失敗
firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
assertSucceeds(pr: Promise) => Promise
如果輸入成功,且 遭到拒絕。使用此方法斷言資料庫是否讀取或 寫入成功
firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
clearFirestoreData({ projectId: string }) => Promise
這個方法會清除叢集中特定專案的所有資料 執行本機運作的 Firestore 執行個體測試完成後,請使用這個方法進行清除。
firebase.clearFirestoreData({ projectId: "my-test-project" });
Realtime Database
Realtime Database
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
可用來建立以特定使用者身分驗證的應用程式,以在測試中使用。
傳回與資料庫名稱和驗證相對應的已初始化 Firebase 應用程式 變數覆寫。
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
請使用此項目建立以管理員身分通過驗證的應用程式,以便設定測試狀態。
傳回與資料庫名稱相對應的已初始化管理員 Firebase 應用程式 會在選項中指定。這個應用程式會在讀取及寫入時略過安全性規則 並將結果傳送至資料庫
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
請使用此項目設定資料庫規則。
將規則傳送至本機執行的資料庫。採用以下選項物件: 指出您的「databaseName」您的「規則」視為字串。
firebase
.loadDatabaseRules({
databaseName: "my-database",
rules: "{'rules': {'.read': false, '.write': false}}"
});
apps() => [FirebaseApp]
傳回所有目前初始化的測試和管理員應用程式。
用於在測試期間或測試後清理應用程式 (請注意已初始化的應用程式) ,以便阻止 JavaScript 退出):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
如果輸入內容成功並成功,系統會傳回拒絕的承諾。 輸入內容會遭到拒絕
您可以使用這個選項斷言資料庫讀取或寫入失敗:
firebase.assertFails(app.database().ref("secret").once("value"));
assertSucceeds(pr: Promise) => Promise
傳回在輸入成功時成功的承諾,如果輸入內容遭拒,就會遭到拒絕。
使用此方法斷言資料庫讀取或寫入成功:
firebase.assertSucceeds(app.database().ref("public").once("value"));
Cloud Storage
Cloud Storage
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
可用來建立以特定使用者身分驗證的應用程式,以在測試中使用。
傳回與儲存空間值區名稱相對應的已初始化 Firebase 應用程式 和 auth 變數覆寫
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
您可以使用這個選項建立以管理員身分驗證的應用程式,以便設定測試狀態。
傳回已初始化的管理員 Firebase 應用程式,該應用程式與選項中指定的儲存空間值區名稱相符。這個應用程式會在讀取及讀取資料時略過安全性規則 寫入值區
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
您可以利用此項目來設定儲存空間值區的規則。
將規則傳送至本機代管的儲存空間值區。接收指定「storageBucket」和「rules」為字串的選項物件。
firebase
.loadStorageRules({
storageBucket: "my-bucket",
rules: fs.readFileSync("/path/to/storage.rules", "utf8")
});
apps() => [FirebaseApp]
傳回所有目前初始化的測試和管理員應用程式。
用於在測試期間或測試後清理應用程式 (請注意已初始化的應用程式) ,以便阻止 JavaScript 退出):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
如果輸入內容成功並成功,系統會傳回拒絕的承諾。 輸入內容會遭到拒絕
可用於斷言儲存值區讀取或寫入作業失敗:
firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());
assertSucceeds(pr: Promise) => Promise
會傳回輸入成功時成功的承諾,如果輸入成功則會遭到拒絕 輸入內容會遭到拒絕
您可以使用這個選項,斷言儲存空間值區讀取或寫入成功:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());
JS SDK 第 8 版適用的 RUT 程式庫 API
選取產品,查看 Firebase Test SDK 用於與模擬器連結的方法。
Cloud Firestore
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
這個方法會傳回與專案對應的已初始化 Firebase 應用程式 選項中指定的 ID 和驗證變數。使用此功能建立應用程式 以特定使用者的身分通過驗證,以便用於測試。
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
這個方法會傳回已初始化的管理員 Firebase 應用程式。執行讀取和寫入作業時,這個應用程式會略過安全性規則。使用此功能建立應用程式 須以管理員的身分通過驗證,才能設定測試狀態。
firebase.initializeAdminApp({ projectId: "my-test-project" });
apps() => [FirebaseApp]
這個方法會傳回目前已初始化的所有測試和管理應用程式。您可以使用這項功能來清除測試期間或測試後的應用程式。
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
這個方法會傳回在輸入成功時遭到拒絕的承諾,或 就會成功。使用此方法斷言資料庫是否讀取或 寫入失敗
firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
assertSucceeds(pr: Promise) => Promise
如果輸入成功,且 遭到拒絕。使用此方法斷言資料庫是否讀取或 寫入成功
firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
clearFirestoreData({ projectId: string }) => Promise
這個方法會清除叢集中特定專案的所有資料 執行本機運作的 Firestore 執行個體測試完成後,請使用這個方法進行清除。
firebase.clearFirestoreData({ projectId: "my-test-project" });
Realtime Database
Realtime Database
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
可用來建立以特定使用者身分驗證的應用程式,以在測試中使用。
傳回與資料庫名稱和驗證相對應的已初始化 Firebase 應用程式 變數覆寫。
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
請使用此項目建立以管理員身分通過驗證的應用程式,以便設定測試狀態。
傳回與資料庫名稱相對應的已初始化管理員 Firebase 應用程式 會在選項中指定。這個應用程式會在讀取及寫入時略過安全性規則 並將結果傳送至資料庫
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
請使用此項目設定資料庫規則。
將規則傳送至本機執行的資料庫。採用以下選項物件: 指出您的「databaseName」您的「規則」視為字串。
firebase
.loadDatabaseRules({
databaseName: "my-database",
rules: "{'rules': {'.read': false, '.write': false}}"
});
apps() => [FirebaseApp]
傳回所有目前初始化的測試和管理員應用程式。
用於在測試期間或測試後清理應用程式 (請注意已初始化的應用程式) ,以便阻止 JavaScript 退出):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
如果輸入內容成功並成功,系統會傳回拒絕的承諾。 輸入內容會遭到拒絕
您可以使用這個選項斷言資料庫讀取或寫入失敗:
firebase.assertFails(app.database().ref("secret").once("value"));
assertSucceeds(pr: Promise) => Promise
傳回在輸入成功時成功的承諾,如果輸入內容遭拒,就會遭到拒絕。
使用此方法斷言資料庫讀取或寫入成功:
firebase.assertSucceeds(app.database().ref("public").once("value"));
Cloud Storage
Cloud Storage
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
可用來建立以特定使用者身分驗證的應用程式,以在測試中使用。
傳回與儲存空間值區名稱相對應的已初始化 Firebase 應用程式 和 auth 變數覆寫
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
您可以使用這個選項建立以管理員身分驗證的應用程式,以便設定測試狀態。
傳回已初始化的管理員 Firebase 應用程式,該應用程式與選項中指定的儲存空間值區名稱相符。這個應用程式會在讀取及讀取資料時略過安全性規則 寫入值區
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
您可以利用此項目來設定儲存空間值區的規則。
將規則傳送至本機代管的儲存空間值區。接收指定「storageBucket」和「rules」為字串的選項物件。
firebase
.loadStorageRules({
storageBucket: "my-bucket",
rules: fs.readFileSync("/path/to/storage.rules", "utf8")
});
apps() => [FirebaseApp]
傳回所有目前初始化的測試和管理員應用程式。
用於在測試期間或測試後清理應用程式 (請注意已初始化的應用程式) ,以便阻止 JavaScript 退出):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
如果輸入內容成功並成功,系統會傳回拒絕的承諾。 輸入內容會遭到拒絕
可用於斷言儲存值區讀取或寫入作業失敗:
firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());
assertSucceeds(pr: Promise) => Promise
會傳回輸入成功時成功的承諾,如果輸入成功則會遭到拒絕 輸入內容會遭到拒絕
您可以使用這個選項,斷言儲存空間值區讀取或寫入成功:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());