Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Criar testes de unidade

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

O Firebase Local Emulator Suite facilita a validação completa dos recursos e do comportamento do seu aplicativo . Também é uma ótima ferramenta para verificar as configurações das regras de segurança do Firebase. Use os emuladores do Firebase para executar e automatizar testes de unidade em um ambiente local. Os métodos descritos neste documento devem ajudá-lo a criar e automatizar testes de unidade para seu aplicativo que validam suas regras.

Se ainda não o fez, configure os Firebase Emulators .

Antes de executar o emulador

Antes de começar a usar o emulador, lembre-se do seguinte:

  • O emulador carregará inicialmente as regras especificadas no campo firestore.rules ou 'storage.rules' do seu arquivo firebase.json . Se o arquivo não existir e você não usar o loadFirestoreRules ou 'loadStorageRules' conforme descrito abaixo, o emulador tratará todos os projetos como tendo regras abertas.
  • Embora a maioria dos SDKs do Firebase funcione diretamente com os emuladores, apenas a biblioteca @firebase/rules-unit-testing é compatível com a auth nas regras de segurança, facilitando muito os testes de unidade. Além disso, a biblioteca oferece suporte a alguns recursos específicos do emulador, como limpar todos os dados, conforme listado abaixo.
  • Os emuladores também aceitarão tokens de autenticação do Firebase de produção fornecidos por meio de SDKs de cliente e avaliarão as regras de acordo, o que permite conectar seu aplicativo diretamente aos emuladores em testes manuais e de integração.

Diferenças entre os emuladores de banco de dados e a produção

  • Você não precisa criar explicitamente uma instância de banco de dados. O emulador criará automaticamente qualquer instância de banco de dados acessada.
  • Cada novo banco de dados é iniciado com regras fechadas, portanto, usuários não administradores não poderão ler ou gravar.
  • Cada banco de dados emulado aplica os limites e cotas do plano Spark (mais notavelmente, isso limita cada instância a 100 conexões simultâneas).
  • Qualquer banco de dados aceitará a string "owner" como um token de autenticação de administrador.
  • Atualmente, os emuladores não têm interações funcionais com outros produtos Firebase. Notavelmente, o fluxo normal do Firebase Authentication não funciona. Em vez disso, você pode usar o método initializeTestApp() na biblioteca rules-unit-testing , que usa um campo de auth . O objeto do Firebase criado com esse método se comporta como se tivesse sido autenticado com êxito como qualquer entidade que você fornecer. Se você passar null , ele se comportará como um usuário não autenticado ( auth != null falharão, por exemplo).

Interagindo com o emulador do Realtime Database

Uma instância de produção do Firebase Realtime Database pode ser acessada em um subdomínio de firebaseio.com e você pode acessar a API REST assim:

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

O emulador é executado localmente e está disponível em localhost:9000 . Para interagir com uma instância de banco de dados específica, você terá que usar o parâmetro de consulta ns para especificar o nome do banco de dados.

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

Execute testes de unidade local com a versão 9 do SDK do JavaScript

O Firebase distribui uma biblioteca de teste de unidade de regras de segurança com o SDK JavaScript da versão 9 e o SDK da versão 8. As APIs da biblioteca são significativamente diferentes. Recomendamos a biblioteca de testes v9, que é mais simplificada e requer menos configuração para se conectar a emuladores e, assim, evitar com segurança o uso acidental de recursos de produção. Para compatibilidade com versões anteriores, continuamos a disponibilizar a biblioteca de teste v8 .

Use o módulo @firebase/rules-unit-testing para interagir com o emulador executado localmente. Se você obtiver tempos limite ou erros ECONNREFUSED , verifique novamente se o emulador está realmente em execução.

É altamente recomendável usar uma versão recente do Node.js para que você possa usar a notação async/await . Quase todo o comportamento que você pode querer testar envolve funções assíncronas, e o módulo de teste foi projetado para funcionar com código baseado em Promise.

A biblioteca v9 Rules Unit Testing está sempre ciente dos emuladores e nunca afeta seus recursos de produção.

Você importa a biblioteca usando instruções de importação modulares v9. Por exemplo:

import {
  assertFails,
  assertSucceeds,
  initializeTestEnvironment,
  RulesTestEnvironment,
} 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.

Uma vez importado, a implementação de testes de unidade envolve:

  • Criando e configurando um RulesTestEnvironment com uma chamada para initializeTestEnvironment .
  • Configurando dados de teste sem acionar Regras, usando um método conveniente que permite ignorá-los temporariamente, RulesTestEnvironment.withSecurityRulesDisabled .
  • Configurando o conjunto de testes e ganchos por teste antes/depois com chamadas para limpar dados de teste e ambiente, como RulesTestEnvironment.cleanup() ou RulesTestEnvironment.clearFirestore() .
  • Implementação de casos de teste que imitam estados de autenticação usando RulesTestEnvironment.authenticatedContext e RulesTestEnvironment.unauthenticatedContext .

Métodos comuns e funções de utilidade

Consulte também os métodos de teste específicos do emulador no SDK v9 .

initializeTestEnvironment() => RulesTestEnvironment

Esta função inicializa um ambiente de teste para teste de unidade de regras. Chame esta função primeiro para configuração de teste. A execução bem-sucedida requer que os emuladores estejam em execução.

A função aceita um objeto opcional que define um TestEnvironmentConfig , que pode consistir em um ID de projeto e definições de configuração do emulador.

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

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

Esse método cria um RulesTestContext , que se comporta como um usuário de autenticação autenticado. As solicitações criadas por meio do contexto retornado terão um token de autenticação simulado anexado. Opcionalmente, passe um objeto que defina declarações personalizadas ou substituições para cargas de token de autenticação.

Use o objeto de contexto de teste retornado em seus testes para acessar quaisquer instâncias de emulador configuradas, incluindo aquelas configuradas com 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

Esse método cria um RulesTestContext , que se comporta como um cliente que não está conectado via Autenticação. As solicitações criadas por meio do contexto retornado não terão tokens de autenticação do Firebase anexados.

Use o objeto de contexto de teste retornado em seus testes para acessar quaisquer instâncias de emulador configuradas, incluindo aquelas configuradas com 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()

Execute uma função de configuração de teste com um contexto que se comporta como se as regras de segurança estivessem desabilitadas.

Esse método usa uma função de retorno de chamada, que usa o contexto de desvio de regras de segurança e retorna uma promessa. O contexto será destruído assim que a promessa for resolvida/rejeitada.

RulesTestEnvironment.cleanup()

Esse método destrói todos os RulesTestContexts criados no ambiente de teste e limpa os recursos subjacentes, permitindo uma saída limpa.

Este método não altera o estado dos emuladores de forma alguma. Para redefinir dados entre testes, use o método clear data específico do emulador do aplicativo.

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

Esta é uma função de utilidade de caso de teste.

A função afirma que a promessa fornecida que envolve uma operação de emulador será resolvida sem violações de regras de segurança.

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

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

Esta é uma função de utilidade de caso de teste.

A função afirma que a promessa fornecida que envolve uma operação de emulador será rejeitada com uma violação de regras de segurança.

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

Métodos específicos do emulador

Consulte também métodos de teste comuns e funções de utilitário no SDK v9 .

Cloud Firestore

Cloud Firestore

RulesTestEnvironment.clearFirestore() => Promise<void>

Este método limpa os dados no banco de dados do Firestore que pertencem ao projectId configurado para o emulador do Firestore.

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

Este método obtém uma instância do Firestore para este contexto de teste. A instância do SDK do cliente Firebase JS retornada pode ser usada com as APIs do SDK do cliente (v9 modular ou compatível com v9).

Banco de dados em tempo real

Banco de dados em tempo real

RulesTestEnvironment.clearDatabase() => Promise<void>

Este método limpa os dados do Realtime Database que pertencem ao projectId configurado para o emulador do Realtime Database.

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

Obtenha uma instância do Realtime Database para este contexto de teste. A instância do SDK do cliente Firebase JS retornada pode ser usada com as APIs do SDK do cliente (v9 modular ou compatível com v9). O método aceita uma URL da instância do Realtime Database. Se especificado, retorna uma instância para uma versão emulada do namespace com parâmetros extraídos da URL.

Armazenamento na núvem

Armazenamento na núvem

RulesTestEnvironment.clearStorage() => Promise<void>

Este método limpa objetos e metadados em buckets de armazenamento pertencentes ao projectId configurado para o emulador do Cloud Storage.

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

Esse método retorna uma instância de armazenamento configurada para se conectar ao emulador. O método aceita um URL gs:// para o Firebase Storage Bucket para teste. Se especificado, retorna uma instância do Storage para uma versão emulada do nome do bucket.

Execute testes de unidade local com o SDK do JavaScript v8

Selecione um produto para ver os métodos usados ​​pelo Firebase Test SDK para interagir com o emulador.

Cloud Firestore

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

Esse método retorna um aplicativo do Firebase inicializado correspondente ao ID do projeto e à variável de autenticação especificada nas opções. Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

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

initializeAdminApp({ projectId: string }) => FirebaseApp

Este método retorna um aplicativo do Firebase de administrador inicializado. Este aplicativo ignora as regras de segurança ao realizar leituras e gravações. Use isso para criar um aplicativo autenticado como administrador para definir o estado dos testes.

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

apps() => [FirebaseApp] Este método retorna todos os aplicativos de teste e administração inicializados no momento. Use isso para limpar aplicativos entre ou após os testes.

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

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

Esse método envia regras para um banco de dados executado localmente. Leva um objeto que especifica as regras como uma string. Use este método para definir as regras do seu banco de dados.

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

assertFails(pr: Promise) => Promise

Esse método retorna uma promessa que é rejeitada se a entrada for bem-sucedida ou que será bem-sucedida se a entrada for rejeitada. Use isso para confirmar se uma leitura ou gravação de banco de dados falhar.

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

assertSucceeds(pr: Promise) => Promise

Esse método retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada. Use isso para confirmar se uma leitura ou gravação de banco de dados for bem-sucedida.

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

clearFirestoreData({ projectId: string }) => Promise

Esse método limpa todos os dados associados a um projeto específico na instância do Firestore em execução localmente. Use este método para limpar após os testes.

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

Banco de dados em tempo real

Banco de dados em tempo real

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

Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

Retorna um aplicativo do Firebase inicializado correspondente ao nome do banco de dados e à substituição da variável de autenticação especificada nas opções.

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

initializeAdminApp({ databaseName: string }) => FirebaseApp

Use isso para criar um aplicativo autenticado como administrador para configurar o estado para testes.

Retorna um aplicativo do Firebase de administrador inicializado correspondente ao nome do banco de dados especificado nas opções. Este aplicativo ignora as regras de segurança ao ler e gravar no banco de dados.

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

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

Use isso para definir as regras do seu banco de dados.

Envia regras para um banco de dados executado localmente. Recebe um objeto de opções que especifica seu "databaseName" e suas "regras" como strings.

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

apps() => [FirebaseApp]

Retorna todos os aplicativos de teste e administração inicializados no momento.

Use isso para limpar aplicativos entre ou após os testes (observe que os aplicativos inicializados com ouvintes ativos impedem que o JavaScript saia):

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

assertFails(pr: Promise) => Promise

Retorna uma promessa que é rejeitada se a entrada for bem-sucedida e bem-sucedida se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de banco de dados falha:

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

assertSucceeds(pr: Promise) => Promise

Retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de banco de dados foi bem-sucedida:

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

Armazenamento na núvem

Armazenamento na núvem

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

Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

Retorna um aplicativo do Firebase inicializado correspondente ao nome do intervalo de armazenamento e à modificação da variável de autenticação especificada nas opções.

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

initializeAdminApp({ storageBucket: string }) => FirebaseApp

Use isso para criar um aplicativo autenticado como administrador para configurar o estado para testes.

Retorna um aplicativo do Firebase de administrador inicializado correspondente ao nome do bucket de armazenamento especificado nas opções. Este aplicativo ignora as regras de segurança ao ler e gravar no bucket.

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

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

Use isso para definir as regras do seu bucket de armazenamento.

Envia regras para buckets de armazenamento gerenciados localmente. Recebe um objeto de opções que especifica seu "storageBucket" e suas "regras" como strings.

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

apps() => [FirebaseApp]

Retorna todos os aplicativos de teste e administração inicializados no momento.

Use isso para limpar aplicativos entre ou após os testes (observe que os aplicativos inicializados com ouvintes ativos impedem que o JavaScript saia):

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

assertFails(pr: Promise) => Promise

Retorna uma promessa que é rejeitada se a entrada for bem-sucedida e bem-sucedida se a entrada for rejeitada.

Use isso para afirmar que a leitura ou gravação de um bucket de armazenamento falha:

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

assertSucceeds(pr: Promise) => Promise

Retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de bucket de armazenamento foi bem-sucedida:

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

API da biblioteca RUT para JS SDK v8

Selecione um produto para ver os métodos usados ​​pelo Firebase Test SDK para interagir com o emulador.

Cloud Firestore

Cloud Firestore

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

Esse método retorna um aplicativo do Firebase inicializado correspondente ao ID do projeto e à variável de autenticação especificada nas opções. Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

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

initializeAdminApp({ projectId: string }) => FirebaseApp

Este método retorna um aplicativo do Firebase de administrador inicializado. Este aplicativo ignora as regras de segurança ao realizar leituras e gravações. Use isso para criar um aplicativo autenticado como administrador para definir o estado dos testes.

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

apps() => [FirebaseApp] Este método retorna todos os aplicativos de teste e administração inicializados no momento. Use isso para limpar aplicativos entre ou após os testes.

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

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

Esse método envia regras para um banco de dados executado localmente. Leva um objeto que especifica as regras como uma string. Use este método para definir as regras do seu banco de dados.

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

assertFails(pr: Promise) => Promise

Esse método retorna uma promessa que é rejeitada se a entrada for bem-sucedida ou que será bem-sucedida se a entrada for rejeitada. Use isso para confirmar se uma leitura ou gravação de banco de dados falhar.

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

assertSucceeds(pr: Promise) => Promise

Esse método retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada. Use isso para confirmar se uma leitura ou gravação de banco de dados for bem-sucedida.

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

clearFirestoreData({ projectId: string }) => Promise

Esse método limpa todos os dados associados a um projeto específico na instância do Firestore em execução localmente. Use este método para limpar após os testes.

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

Banco de dados em tempo real

Banco de dados em tempo real

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

Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

Retorna um aplicativo do Firebase inicializado correspondente ao nome do banco de dados e à substituição da variável de autenticação especificada nas opções.

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

initializeAdminApp({ databaseName: string }) => FirebaseApp

Use isso para criar um aplicativo autenticado como administrador para configurar o estado para testes.

Retorna um aplicativo do Firebase de administrador inicializado correspondente ao nome do banco de dados especificado nas opções. Este aplicativo ignora as regras de segurança ao ler e gravar no banco de dados.

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

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

Use isso para definir as regras do seu banco de dados.

Envia regras para um banco de dados executado localmente. Recebe um objeto de opções que especifica seu "databaseName" e suas "regras" como strings.

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

apps() => [FirebaseApp]

Retorna todos os aplicativos de teste e administração inicializados no momento.

Use isso para limpar aplicativos entre ou após os testes (observe que os aplicativos inicializados com ouvintes ativos impedem que o JavaScript saia):

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

assertFails(pr: Promise) => Promise

Retorna uma promessa que é rejeitada se a entrada for bem-sucedida e bem-sucedida se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de banco de dados falha:

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

assertSucceeds(pr: Promise) => Promise

Retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de banco de dados foi bem-sucedida:

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

Armazenamento na núvem

Armazenamento na núvem

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

Use isso para criar um aplicativo autenticado como um usuário específico para uso em testes.

Retorna um aplicativo do Firebase inicializado correspondente ao nome do intervalo de armazenamento e à modificação da variável de autenticação especificada nas opções.

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

initializeAdminApp({ storageBucket: string }) => FirebaseApp

Use isso para criar um aplicativo autenticado como administrador para configurar o estado para testes.

Retorna um aplicativo do Firebase de administrador inicializado correspondente ao nome do bucket de armazenamento especificado nas opções. Este aplicativo ignora as regras de segurança ao ler e gravar no bucket.

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

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

Use isso para definir as regras do seu bucket de armazenamento.

Envia regras para buckets de armazenamento gerenciados localmente. Recebe um objeto de opções que especifica seu "storageBucket" e suas "regras" como strings.

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

apps() => [FirebaseApp]

Retorna todos os aplicativos de teste e administração inicializados no momento.

Use isso para limpar aplicativos entre ou após os testes (observe que os aplicativos inicializados com ouvintes ativos impedem que o JavaScript saia):

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

assertFails(pr: Promise) => Promise

Retorna uma promessa que é rejeitada se a entrada for bem-sucedida e bem-sucedida se a entrada for rejeitada.

Use isso para afirmar que a leitura ou gravação de um bucket de armazenamento falha:

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

assertSucceeds(pr: Promise) => Promise

Retorna uma promessa que será bem-sucedida se a entrada for bem-sucedida e será rejeitada se a entrada for rejeitada.

Use isso para afirmar que uma leitura ou gravação de bucket de armazenamento foi bem-sucedida:

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