前往主控台

Build unit tests

The Firebase Emulators make it easier to fully validate your app's behavior and verify your Firebase Security Rules configurations. Use the Firebase Emulators to run and automate unit tests in a local environment. The methods outlined in this document should help you as you build and automate unit tests for your app that validate your Rules.

If you haven't already, set up the Firebase Emulators.

Before you run the emulator

Before you start using the emulator, keep in mind the following:

  • The emulator will initially load the rules specified in the firestore.rules field of your firebase.json file. If the file does not exist and you don't use the loadFirestoreRules method as described below, the emulator treats all projects as having open rules.
  • While many SDKs work with the emulators, only the @firebase/testing Node.js module supports mocking auth in Security Rules, making unit tests much easier. In addition, the module supports a few emulator-specific features like clearing all data, as listed below.
  • The emulators will also accept production Firebase Auth tokens provided through Client SDKs and evaluate rules accordingly, which allows connecting your application directly to the emulators in integration and manual tests.

Differences between the emulator and production

  • You do not have to explicitly create a database instance. The emulator will automatically create any database instance that is accessed.
  • Each new database is started with closed rules, so non-admin users will not be able to read or write.
  • Each emulated database applies the Spark plan limits and quotas (most notably, this limits each instance to 100 concurrent connections).
  • Any database will accept the string "owner" as an admin auth token.
  • The emulators do not currently have working interactions with other Firebase products. Notably, the normal Firebase Authentication flow does not work. Instead, you can use the initializeTestApp() method in the testing module, which takes an auth field. The Firebase object created using this method behaves as if it has successfully authenticated as whatever entity you provide. If you pass in null, it will behave as an unauthenticated user (auth != null rules will fail, for example).

Run local tests

Use the @firebase/testing module to interact with the emulator that runs locally. If you get timeouts or ECONNREFUSED errors, double-check that the emulator is actually running.

We strongly recommend using a recent version of Node.js so you can use async/await notation. Almost all of the behavior you might want to test involves asynchronous functions, and the testing module is designed to work with Promise-based code.

Emulator methods

Select a product to see the methods the emulator module exposes.

Cloud Firestore

Cloud Firestore

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

This method returns an initialized Firebase app corresponding to the project ID and auth variable specified in the options. Use this to create an app authenticated as a specific user to use in tests.

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", email: "alice@example.com" }
});

initializeAdminApp({ projectId: string }) => FirebaseApp

This method returns an initialized admin Firebase app. This app bypasses security rules when performing reads and writes. Use this to create an app authenticated as an admin to set state for tests.

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

apps() => [FirebaseApp] This method returns all the currently initialized test and admin apps. Use this to clean up apps between or after tests.

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

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

This method sends rules to a locally running database. It takes an object that specifies the rules as a string. Use this method to set your database's rules.

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

assertFails(pr: Promise) => Promise

This method returns a promise that is rejected if the input succeeds or that succeeds if the input is rejected. Use this to assert if a database read or write fails.

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

assertSucceeds(pr: Promise) => Promise

This method returns a promise that succeeds if the input succeeds and is rejected if the input is rejected. Use this to assert if a database read or write succeeds.

firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
    

clearFirestoreData({ projectId: string }) => Promise

This method clears all data associated with a particular project in the locally running Firestore instance. Use this method to clean-up after tests.

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

Realtime Database

Realtime Database

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

Use this to create an app authenticated as a specific user to use in tests.

Returns an initialized firebase app corresponding to the database name and auth variable override specified in options.

firebase.initializeTestApp({
  databaseName: "my-database",
  auth: { uid: "alice" }
});

initializeAdminApp({ databaseName: string }) => FirebaseApp

Use this to create an app authenticated as an admin to set up state for tests.

Returns an initialized admin firebase app corresponding to the database name specified in options. This app bypasses security rules when reading and writing to the database.

firebase.initializeAdminApp({ databaseName: "my-database" });

loadDatabaseRules({ databaseName: string, rules: Object }) => Promise

Use this to set your database's rules.

Sends rules to a locally running database. Takes an options object that specifies your "databaseName" and your "rules" as strings.

firebase
      .loadDatabaseRules({
        databaseName: "my-database",
        rules: "{'rules': {'.read': false, '.write': false}}"
      });

apps() => [FirebaseApp]

Returns all the currently initialized test and admin apps.

Use this to clean up apps between or after tests (note that initialized apps with active listeners prevent JavaScript from exiting):

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

assertFails(pr: Promise) => Promise

Returns a promise that is rejected if the input succeeds and succeeds if the input is rejected.

Use this to assert that a database read or write fails:

firebase.assertFails(app.database().ref("secret").once("value"));

assertSucceeds(pr: Promise) => Promise

Returns a promise that succeeds if the input succeeds and is rejected if the input is rejected.

Use this to assert that a database read or write succeeds:

firebase.assertSucceeds(app.database().ref("public").once("value"));