Compila pruebas de unidades

Los emuladores de Firebase te ayudan a validar exhaustivamente el comportamiento de tu app y a verificar la configuración de las reglas de seguridad de Firebase. Usa los emuladores de Firebase para ejecutar y automatizar pruebas de unidades en un entorno local. Los métodos descritos en este documento te pueden ayudar en la compilación y automatización de pruebas de unidades para tu app que validen las reglas aplicadas.

Si aún no lo has hecho, configura los emuladores de Firebase.

Antes de que ejecutes el emulador

Antes de comenzar a usar el emulador, ten en cuenta lo siguiente:

  • Inicialmente, el emulador cargará las reglas especificadas en los campos firestore.rules o “storage.rules” de tu archivo firebase.json. Si el archivo no existe y no usas los métodos loadFirestoreRules o “loadStorageRules” como se describe a continuación, el emulador trata todos los proyectos como si tuvieran reglas abiertas.
  • Si bien la mayoría de los SDK de Firebase funcionan con los emuladores de forma directa, solo la biblioteca @firebase/rules-unit-testing admite simulaciones de auth en las reglas de seguridad, lo que facilita considerablemente las pruebas de unidades. Además, la biblioteca admite algunas funciones específicas del emulador, como borrar todos los datos, según se detalla a continuación.
  • Los emuladores también aceptarán tokens de producción de Firebase Auth proporcionados a través de SDK cliente y evaluarán las reglas en consecuencia, lo que te permite conectar tu aplicación directamente a los emuladores en pruebas de integración y manuales.

Diferencias entre los emuladores de bases de datos y la producción

  • No es necesario crear una instancia de base de datos de manera explícita. El emulador creará automáticamente cualquier instancia de base de datos a la que se acceda.
  • Cada base de datos nueva se inicia con reglas cerradas, por lo que los usuarios que no sean administradores no podrán realizar operaciones de lectura ni escritura.
  • Se aplican los límites y cuotas del plan Spark a todas las bases de datos emuladas (en particular, esto limita cada instancia a 100 conexiones simultáneas).
  • Cualquier base de datos aceptará la string "owner" como token de autenticación del administrador.
  • Actualmente los emuladores no tienen interacciones operativas con otros productos de Firebase. En particular, no funciona el flujo normal de Firebase Authentication. En su lugar, puedes usar el método initializeTestApp() en la biblioteca rules-unit-testing, que emplea un campo auth. El objeto de Firebase que se cree con este método se comportará como si se autenticara correctamente al igual que cualquier entidad proporcionada. Si pasas null, se comportará como un usuario no autenticado (por ejemplo, fallarán las reglas auth != null).

Ejecuta pruebas locales

Usa el módulo @firebase/rules-unit-testing para interactuar con el emulador que se ejecuta de manera local. Si recibes errores ECONNREFUSED o de tiempo de espera, vuelve a verificar que se esté ejecutando el emulador.

Recomendamos usar una versión reciente de Node.js, de modo que puedas utilizar la notación async/await. Casi todo comportamiento que quieras probar involucra funciones asíncronas. El módulo de pruebas está diseñado para funcionar con código basado en promesas.

Interactúa con el emulador de Realtime Database

Se puede acceder a una instancia de producción de Firebase Realtime Database en un subdominio de firebaseio.com, y puedes acceder a la API de REST de la siguiente manera:

https://<database_name>.firebaseio.com/path/to/my/data.json

El emulador se ejecuta de manera local y está disponible en localhost:9000. Para interactuar con una instancia de base de datos específica, deberás usar el parámetro de búsqueda ns a fin de especificar el nombre de la base de datos.

http://localhost:9000/path/to/my/data.json?ns=<database_name>

Métodos del SDK de Test

Selecciona un producto y conoce los métodos que usa el SDK de Firebase Test para interactuar con el emulador.

Cloud Firestore

Cloud Firestore

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

Este método muestra una app de Firebase inicializada correspondiente al ID del proyecto y la variable de auth especificada en las opciones. Úsalo para crear una app autenticada como un usuario específico que puedes emplear durante las pruebas.

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

initializeAdminApp({ projectId: string }) => FirebaseApp

Este método muestra una app de administración de Firebase inicializada, que omite las reglas de seguridad cuando realiza operaciones de lectura y escritura. Usa el método a fin de crear una app autenticada como un administrador para configurar el estado de las pruebas.

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

apps() => [FirebaseApp] Este método muestra todas las apps de administración y pruebas inicializadas actualmente. Úsalo para limpiar las apps entre pruebas o después de ellas.

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

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

Este método envía reglas a una base de datos que se ejecuta localmente. Requiere un objeto que especifique las reglas como string. Usa este método para configurar las reglas de tu base de datos.

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

assertFails(pr: Promise) => Promise

Este método muestra una promesa que se rechaza si la entrada es correcta o se cumple correctamente si la entrada se rechaza. Úsalo para confirmar si fallan las operaciones de lectura o escritura de una base de datos.

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

assertSucceeds(pr: Promise) => Promise

Este método muestra una promesa que se cumple correctamente si la entrada es correcta o se rechaza si la entrada se rechaza. Úsalo para confirmar si se completan correctamente las operaciones de lectura o escritura de una base de datos.

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

clearFirestoreData({ projectId: string }) => Promise

Este método borra todos los datos asociados a un proyecto determinado de la instancia de Firestore que se ejecuta de manera local. Usa este método para realizar la limpieza después de las pruebas.

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

Realtime Database

Realtime Database

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

Úsalo para crear una app autenticada como un usuario específico que puedes usar durante las pruebas.

Muestra una app de Firebase inicializada correspondiente al nombre de la base de datos y la anulación de la variable auth que se especificó en las opciones.

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

initializeAdminApp({ databaseName: string }) => FirebaseApp

Úsalo a fin de crear una app autenticada como un administrador para configurar el estado de las pruebas.

Muestra una app de administración de Firebase inicializada correspondiente al nombre de la base de datos que se especificó en las opciones. Esta app ignora las reglas de seguridad al momento de leer o escribir en la base de datos.

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

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

Úsalo para configurar las reglas de tu base de datos.

Envía reglas a una base de datos que se ejecuta localmente. Toma un objeto de opciones que indica tu “databaseName” y tus “rules” como strings.

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

apps() => [FirebaseApp]

Muestra todas las apps de administración y prueba inicializadas.

Úsalo para limpiar las apps entre pruebas o a su término (ten en cuenta que las apps inicializadas con objetos de escucha activos evitan la salida de JavaScript):

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

assertFails(pr: Promise) => Promise

Muestra una promesa que se rechaza si la entrada es correcta y se cumple correctamente si se rechaza la entrada.

Úsalo para confirmar que fallan las operaciones de lectura o escritura de una base de datos:

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

assertSucceeds(pr: Promise) => Promise

Muestra una promesa que se cumple correctamente si la entrada es correcta y se rechaza si la entrada se rechaza.

Úsalo para declarar que una base de datos puede leer o escribir:

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

Cloud Storage

Cloud Storage

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

Úsalo para crear una app autenticada como un usuario específico que puedes usar durante las pruebas.

Muestra una app de Firebase inicializada correspondiente al nombre del bucket de almacenamiento y la anulación de la variable auth que se especificó en las opciones.

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

initializeAdminApp({ storageBucket: string }) => FirebaseApp

Úsalo a fin de crear una app autenticada como un administrador para configurar el estado de las pruebas.

Muestra una app de administración de Firebase inicializada correspondiente al nombre del bucket de almacenamiento especificado en las opciones. Esta app omite las reglas de seguridad al momento de leer y escribir en el bucket.

firebase.initializeAdminApp({ storageBucket: "my-bucket" });

loadStorageRules({ storageBucket: string, rules: Object }) => Promise

Úsalo para configurar las reglas de tu bucket de almacenamiento.

Envía reglas a buckets de almacenamiento administrados de manera local. Toma un objeto de opciones que indica tu “storageBucket” y tus “reglas” como strings.

firebase
      .loadStorageRules({
        storageBucket: "my-bucket",
        rules: fs.readFileSync("/path/to/storage.rules", "utf8")
      });

apps() => [FirebaseApp]

Muestra todas las apps de administración y prueba inicializadas.

Úsalo para limpiar las apps entre pruebas o a su término (ten en cuenta que las apps inicializadas con objetos de escucha activos evitan la salida de JavaScript):

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

assertFails(pr: Promise) => Promise

Muestra una promesa que se rechaza si la entrada es correcta y se cumple correctamente si se rechaza la entrada.

Úsalo para confirmar que falla la lectura o escritura de un bucket de almacenamiento:

firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());

assertSucceeds(pr: Promise) => Promise

Muestra una promesa que se cumple correctamente si la entrada es correcta y que se rechaza si la entrada se rechaza.

Úsalo para confirmar que se logró la lectura o escritura de un bucket de almacenamiento:

firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());