Test delle unità di creazione

Firebase Local Emulator Suite semplificano la convalida completa delle funzionalità e del comportamento della tua app. È anche un ottimo strumento per verificare le configurazioni di Firebase Security Rules. Utilizza gli emulatori Firebase per eseguire e automatizzare i test delle unità in un ambiente locale. I metodi descritti in questo documento dovrebbero aiutarti durante la creazione e l'automazione dei test delle unità per la tua app che convalidano Rules.

Se non lo hai già fatto, configura Firebase Emulators.

Prima di eseguire l'emulatore

Prima di iniziare a utilizzare l'emulatore, tieni presente quanto segue:

  • L'emulatore caricherà inizialmente le regole specificate nel campo firestore.rules o "storage.rules" del file firebase.json. Se il file non esiste e non utilizzi il metodo loadFirestoreRules o "loadStorageRules" come descritto di seguito, l'emulatore considera tutti i progetti come regole aperte.
  • Anche se la maggior parte degli SDK Firebase funziona direttamente con gli emulatori, solo la libreria @firebase/rules-unit-testing supporta la simulazione di auth nelle regole di sicurezza, semplificando notevolmente i test di unità. Inoltre, la libreria supporta alcune funzionalità specifiche dell'emulatore, come l'eliminazione di tutti i dati, come elencato di seguito.
  • Gli emulatori accetteranno anche i token di produzione di Firebase Authentication forniti tramite gli SDK client e valuteranno le regole di conseguenza, il che consente di collegare la tua applicazione direttamente agli emulatori nei test di integrazione e manuali.

Differenze tra gli emulatori di database e la produzione

  • Non è necessario creare esplicitamente un'istanza di database. L'emulatore creerà automaticamente qualsiasi istanza di database a cui viene eseguito l'accesso.
  • Ogni nuovo database viene avviato con regole chiuse, pertanto gli utenti non amministratori non potranno leggere né scrivere.
  • Ogni database emulato applica i limiti e le quote del piano Spark (in particolare, questo limita ogni istanza a 100 connessioni simultanee).
  • Qualsiasi database accetterà la stringa "owner" come token di autenticazione amministratore.
  • Al momento gli emulatori non hanno interazioni funzionanti con altri prodotti Firebase. In particolare, il normale flusso di Firebase Authentication non funziona. Puoi utilizzare invece il metodo initializeTestApp() nella libreria rules-unit-testing, che accetta un campo auth. L'oggetto Firebase creato utilizzando questo metodo si comporta come se fosse stato autenticato correttamente come qualsiasi entità fornita. Se passi null, il valore si comporterà come un utente non autenticato (ad esempio, le regole auth != null non andranno a buon fine).

Interazione con l'emulatore Realtime Database

Un'istanza Realtime Database Firebase di produzione è accessibile da un sottodominio di firebaseio.com e puoi accedere all'API REST come segue:

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

L'emulatore viene eseguito localmente ed è disponibile all'indirizzo localhost:9000. Per interagire con un'istanza del database specifica, dovrai utilizzare il parametro di query ns per specificare il nome del database.

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

Eseguire test locali delle unità con l'SDK JavaScript versione 9

Firebase distribuisce una libreria di test di unità delle regole di sicurezza sia con l'SDK JavaScript di versione 9 sia con l'SDK di versione 8. Le API della libreria sono molto diverse. Consigliamo la libreria di test v9, che è più snella e richiede meno configurazione per connettersi agli emulatori e quindi evitare in modo sicuro l'uso accidentale delle risorse di produzione. Per la compatibilità con le versioni precedenti, continuiamo a mettere a disposizione la libreria di test v8.

Utilizza il modulo @firebase/rules-unit-testing per interagire con l'emulatore eseguito localmente. Se si verificano timeout o errori ECONNREFUSED, verifica che l'emulatore sia effettivamente in esecuzione.

Ti consigliamo vivamente di utilizzare una versione recente di Node.js per poter utilizzare la notazione async/await. Quasi tutti i comportamenti che potresti voler testare richiedono funzioni asincrone e il modulo di test è progettato per funzionare con il codice basato su promesse.

La libreria di test delle unità delle regole 9 è sempre consapevole degli emulatori e non tocca mai le risorse di produzione.

Importa la libreria utilizzando le istruzioni di importazione modulari della versione 9. Ad esempio:

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.

Una volta importati, l'implementazione dei test di unità prevede:

  • Creazione e configurazione di un RulesTestEnvironment con una chiamata a initializeTestEnvironment.
  • Configurare i dati di test senza attivare Rules, utilizzando un metodo di comodità che consente di ignorarli temporaneamente,RulesTestEnvironment.withSecurityRulesDisabled.
  • Configurazione di suite di test e hook prima/dopo per test con chiamate per pulizia dei dati e dell'ambiente di test, ad esempio RulesTestEnvironment.cleanup() o RulesTestEnvironment.clearFirestore().
  • Implementazione di casi di test che simulano gli stati di autenticazione utilizzando RulesTestEnvironment.authenticatedContext e RulesTestEnvironment.unauthenticatedContext.

Metodi comuni e funzioni di utilità

Consulta anche i metodi di test specifici dell'emulatore che utilizzano l'API modulare.

initializeTestEnvironment() => RulesTestEnvironment

Questa funzione inizializza un ambiente di test per i test delle unità delle regole. Chiama prima questa funzione per la configurazione del test. Per una corretta esecuzione è necessario eseguire gli emulatori.

La funzione accetta un oggetto facoltativo che definisce un valore TestEnvironmentConfig, che può essere composto da un ID progetto e dalle impostazioni di configurazione dell'emulatore.

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

Questo metodo crea un RulesTestContext, che si comporta come un utente Authentication autenticato. Alle richieste create tramite il contesto restituito verrà allegato un token Authentication simulato. Se vuoi, puoi passare un oggetto che definisce rivendicazioni personalizzate o superamenti per i payload dei token Authentication.

Utilizza l'oggetto contesto test restituito nei test per accedere a eventuali istanze di emulatore configurate, incluse quelle configurate con 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

Questo metodo crea un RulesTestContext, che si comporta come un client che non ha eseguito l'accesso tramite Authentication. Le richieste create tramite il contesto restituito non avranno token Firebase Auth allegati.

Utilizza l'oggetto contesto test restituito nei test per accedere a eventuali istanze di emulatore configurate, incluse quelle configurate con 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()

Esegui una funzione di configurazione del test con un contesto che si comporta come se le Regole di sicurezza fossero disabilitate.

Questo metodo accetta una funzione di callback, che accetta il contesto di aggiramento delle regole di sicurezza e restituisce una promessa. Il contesto verrà distrutto una volta che la promessa viene risolta/rifiutata.

RulesTestEnvironment.cleanup()

Questo metodo distrugge tutti i RulesTestContexts creati nell'ambiente di test e pulizia delle risorse sottostanti, consentendo un'uscita pulita.

Questo metodo non modifica in alcun modo lo stato degli emulatori. Per reimpostare i dati tra un test e l'altro, utilizza il metodo di cancellazione dei dati specifico dell'emulatore dell'applicazione.

assertSucceeds(pr: Promise<any>)) => Promise<any>

Questa è una funzione di utilità per i casi di test.

La funzione afferma che la Promise fornita che racchiude un'operazione dell'emulatore verrà risolta senza violazioni delle regole di sicurezza.

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

Questa è una funzione di utilità per i casi di test.

La funzione asserisce che la promessa fornita che include un'operazione di emulatore verrà rifiutata con una violazione delle regole di sicurezza.

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

Metodi specifici per l'emulatore

Consulta anche metodi di test e funzioni di utilità comuni che utilizzano l'API modulare.

Cloud Firestore

Cloud Firestore

RulesTestEnvironment.clearFirestore() => Promise<void>

Questo metodo cancella i dati nel database Firestore appartenenti al projectId configurato per l'emulatore Firestore.

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

Questo metodo recupera un'istanza Firestore per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API SDK client (v9 modulare o v9 compatibile).

Realtime Database

Realtime Database

RulesTestEnvironment.clearDatabase() => Promise<void>

Questo metodo cancella i dati in Realtime Database che appartengono al projectId configurato per l'emulatore Realtime Database.

RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;

Recupera un'istanza di Realtime Database per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API dell'SDK client (modulari o con nome, versione 9 o successive). Il metodo accetta un URL dell'istanza Database in tempo reale. Se specificato, restituisce un'istanza per una versione emulata dello spazio dei nomi con i parametri estratti dall'URL.

Cloud Storage

Cloud Storage

RulesTestEnvironment.clearStorage() => Promise<void>

Questo metodo cancella gli oggetti e i metadati nei bucket di archiviazione appartenenti al projectId configurato per l'emulatore Cloud Storage.

RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;

Questo metodo restituisce un'istanza di archiviazione configurata per la connessione all'emulatore. Il metodo accetta un URL gs:// per il bucket Firebase Storage per i test. Se specificato, restituisce un'istanza Storage per una versione emulata del nome del bucket.

Esecuzione dei test delle unità locali con l'SDK JavaScript v8

Seleziona un prodotto per visualizzare i metodi utilizzati dall'SDK Firebase Test per interfacciarsi con l'emulatore.

Cloud Firestore

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

Questo metodo restituisce un'app Firebase inizializzata corrispondente all'ID progetto e alla variabile di autenticazione specificata nelle opzioni. Utilizza questo campo per creare un'app autenticata come utente specifico da usare nei test.

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

initializeAdminApp({ projectId: string }) => FirebaseApp

Questo metodo restituisce un'app Firebase di amministrazione inizializzata. Questa app aggira le regole di sicurezza durante l'esecuzione di letture e scritture. Utilizzalo per creare un'app autenticata come amministratore per impostare lo stato per i test.

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

apps() => [FirebaseApp] Questo metodo restituisce tutte le app di test e di amministrazione attualmente inizializzate. Usa questa opzione per eseguire la pulizia delle app tra o dopo i test.

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

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

Questo metodo invia le regole a un database in esecuzione localmente. Prende un oggetto che specifica le regole come stringa. Utilizza questo metodo per impostare le regole del database.

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

assertFails(pr: Promise) => Promise

Questo metodo restituisce una promessa rifiutata se l'input va a buon fine o che va a buon fine se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database non va a buon fine.

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

assertSucceeds(pr: Promise) => Promise

Questo metodo restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato. Utilizzalo per asserire se la lettura o la scrittura del database va a buon fine.

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

clearFirestoreData({ projectId: string }) => Promise

Questo metodo cancella tutti i dati associati a un determinato progetto nell'istanza Firestore in esecuzione localmente. Utilizza questo metodo per eseguire la pulizia dopo i test.

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

Realtime Database

Realtime Database

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

Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.

Restituisce un'app Firebase inizializzata corrispondente al nome del database e all'override della variabile di autenticazione specificati nelle opzioni.

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

initializeAdminApp({ databaseName: string }) => FirebaseApp

Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.

Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato in options. Quest'app ignora le regole di sicurezza durante la lettura e la scrittura sul database.

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

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

Utilizzalo per impostare le regole del database.

Invia le regole a un database eseguito localmente. Accetta un oggetto opzioni che specifica "databaseName" e "rules" come stringhe.

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

apps() => [FirebaseApp]

Restituisce tutte le app di test e amministrazione attualmente inizializzate.

Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):

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

assertFails(pr: Promise) => Promise

Restituisce una promessa che viene rifiutata se l'input ha esito positivo e viene restituito se l'input viene rifiutato.

Utilizza questa istruzione per verificare che la lettura o la scrittura di un database non vada a buon fine:

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

assertSucceeds(pr: Promise) => Promise

Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.

Utilizzalo per affermare che una lettura o una scrittura del database è andata a buon fine:

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

Cloud Storage

Cloud Storage

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

Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.

Restituisce un'app Firebase inizializzata corrispondente al nome del bucket di archiviazione e all'override della variabile di autenticazione specificati nelle opzioni.

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

initializeAdminApp({ storageBucket: string }) => FirebaseApp

Utilizza questo campo per creare un'app autenticata come amministratore al fine di configurare lo stato per i test.

Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel bucket.

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

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

Utilizzalo per impostare le regole del bucket di archiviazione.

Invia regole a bucket di archiviazione gestiti localmente. Prende un oggetto options che specifica "storageBucket" e "rules" come stringhe.

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

apps() => [FirebaseApp]

Restituisce tutte le app di test e di amministrazione attualmente inizializzate.

Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):

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

assertFails(pr: Promise) => Promise

Restituisce una promessa che viene rifiutata se l'input ha esito positivo e viene restituito se l'input viene rifiutato.

Utilizza questo parametro per verificare che la lettura o la scrittura di un bucket di archiviazione non vada a buon fine:

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

assertSucceeds(pr: Promise) => Promise

Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.

Utilizza questo metodo per verificare che la lettura o la scrittura di un bucket di archiviazione sia andata a buon fine:

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

API della libreria RUT per la versione 8 dell'SDK JS

Seleziona un prodotto per visualizzare i metodi utilizzati dall'SDK di test di Firebase per interagire con l'emulatore.

Cloud Firestore

Cloud Firestore

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

Questo metodo restituisce un'app Firebase inizializzata corrispondente all'ID progetto e alla variabile di autenticazione specificata nelle opzioni. Utilizza questo campo per creare un'app autenticata come utente specifico da usare nei test.

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

initializeAdminApp({ projectId: string }) => FirebaseApp

Questo metodo restituisce un'app Firebase di amministrazione inizializzata. Questa app aggira le regole di sicurezza durante l'esecuzione di letture e scritture. Utilizzalo per creare un'app autenticata come amministratore per impostare lo stato per i test.

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

apps() => [FirebaseApp] Questo metodo restituisce tutte le app di test e di amministrazione attualmente inizializzate. Usa questa opzione per eseguire la pulizia delle app tra o dopo i test.

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

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

Questo metodo invia le regole a un database in esecuzione localmente. Prende un oggetto che specifica le regole come stringa. Utilizza questo metodo per impostare le regole del database.

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

assertFails(pr: Promise) => Promise

Questo metodo restituisce una promessa rifiutata se l'input va a buon fine o che va a buon fine se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database non va a buon fine.

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

assertSucceeds(pr: Promise) => Promise

Questo metodo restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato. Utilizzalo per asserire se la lettura o la scrittura del database va a buon fine.

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

clearFirestoreData({ projectId: string }) => Promise

Questo metodo cancella tutti i dati associati a un determinato progetto nell'istanza Firestore in esecuzione localmente. Utilizza questo metodo per eseguire la pulizia dopo i test.

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

Realtime Database

Realtime Database

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

Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.

Restituisce un'app Firebase inizializzata corrispondente al nome del database e all'override della variabile di autenticazione specificati nelle opzioni.

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

initializeAdminApp({ databaseName: string }) => FirebaseApp

Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.

Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato in options. Quest'app ignora le regole di sicurezza durante la lettura e la scrittura sul database.

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

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

Utilizzalo per impostare le regole del database.

Invia le regole a un database eseguito localmente. Accetta un oggetto opzioni che specifica "databaseName" e "rules" come stringhe.

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

apps() => [FirebaseApp]

Restituisce tutte le app di test e amministrazione attualmente inizializzate.

Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):

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

assertFails(pr: Promise) => Promise

Restituisce una promessa che viene rifiutata se l'input ha esito positivo e viene restituito se l'input viene rifiutato.

Utilizza questa istruzione per verificare che la lettura o la scrittura di un database non vada a buon fine:

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

assertSucceeds(pr: Promise) => Promise

Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.

Utilizzalo per affermare che una lettura o una scrittura del database è andata a buon fine:

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

Cloud Storage

Cloud Storage

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

Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.

Restituisce un'app Firebase inizializzata corrispondente al nome del bucket di archiviazione e all'override della variabile di autenticazione specificati nelle opzioni.

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

initializeAdminApp({ storageBucket: string }) => FirebaseApp

Utilizza questo campo per creare un'app autenticata come amministratore al fine di configurare lo stato per i test.

Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel bucket.

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

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

Utilizzalo per impostare le regole del bucket di archiviazione.

Invia regole a bucket di archiviazione gestiti localmente. Prende un oggetto options che specifica "storageBucket" e "rules" come stringhe.

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

apps() => [FirebaseApp]

Restituisce tutte le app di test e di amministrazione attualmente inizializzate.

Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):

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

assertFails(pr: Promise) => Promise

Restituisce una promessa che viene rifiutata se l'input ha esito positivo e viene restituito se l'input viene rifiutato.

Utilizza questo parametro per verificare che la lettura o la scrittura di un bucket di archiviazione non vada a buon fine:

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

assertSucceeds(pr: Promise) => Promise

Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.

Utilizza questo metodo per verificare che la lettura o la scrittura di un bucket di archiviazione sia andata a buon fine:

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