Firebase Local Emulator Suite упрощает полную проверку функций и поведения вашего приложения. Это также отличный инструмент для проверки настроек Firebase Security Rules . Используйте эмуляторы Firebase для запуска и автоматизации модульных тестов в локальной среде. Методы, изложенные в этом документе, должны помочь вам при создании и автоматизации модульных тестов для вашего приложения, проверяющих ваши Rules .
Если вы еще этого не сделали, настройте эмуляторы Firebase .
Прежде чем запустить эмулятор
Прежде чем начать использовать эмулятор, имейте в виду следующее:
- Эмулятор первоначально загрузит правила, указанные в поле
firestore.rules
илиstorage.rules
вашего файлаfirebase.json
. Если файл не существует и вы не используете методloadFirestoreRules
илиloadStorageRules
, как описано ниже, эмулятор рассматривает все проекты как имеющие открытые правила. - Хотя большинство SDK Firebase работают с эмуляторами напрямую, только библиотека
@firebase/rules-unit-testing
поддерживает имитациюauth
в правилах безопасности, что значительно упрощает модульные тесты. Кроме того, библиотека поддерживает несколько функций, специфичных для эмулятора, таких как очистка всех данных, как указано ниже. - Эмуляторы также будут принимать производственные токены Firebase Auth, предоставленные через клиентские SDK, и соответствующим образом оценивать правила, что позволяет подключать ваше приложение напрямую к эмуляторам при интеграции и ручных тестах.
Отличия эмуляторов баз данных от продакшена
- Вам не нужно явно создавать экземпляр базы данных. Эмулятор автоматически создаст любой экземпляр базы данных, к которому осуществляется доступ.
- Каждая новая база данных запускается с закрытыми правилами, поэтому пользователи, не являющиеся администраторами, не смогут читать или писать.
- Каждая эмулируемая база данных применяет ограничения и квоты плана Spark (в частности, это ограничивает каждый экземпляр 100 одновременными подключениями).
- Любая база данных примет строку
"owner"
в качестве токена аутентификации администратора. - Эмуляторы в настоящее время не взаимодействуют с другими продуктами Firebase. Примечательно, что обычный поток аутентификации Firebase не работает. Вместо этого вы можете использовать метод
initializeTestApp()
в библиотекеrules-unit-testing
, который принимает полеauth
. Объект Firebase, созданный с помощью этого метода, ведет себя так, как будто он успешно прошел аутентификацию как любой предоставленный вами объект. Если вы передадитеnull
, он будет вести себя как неаутентифицированный пользователь (например, правилаauth != null
не будут работать).
Взаимодействие с эмулятором Realtime Database
Экземпляр 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>
Запускайте локальные модульные тесты с помощью JavaScript SDK версии 9.
Firebase распространяет библиотеку модульного тестирования правил безопасности как с SDK JavaScript версии 9, так и с SDK версии 8. API библиотеки существенно отличаются. Мы рекомендуем библиотеку тестирования v9, которая более оптимизирована и требует меньше настроек для подключения к эмуляторам и, таким образом, позволяет безопасно избежать случайного использования производственных ресурсов. В целях обратной совместимости мы продолжаем делать доступной библиотеку тестирования v8 .
- Общие методы тестирования и служебные функции в SDK версии 9.
- Методы тестирования, специфичные для эмулятора, в v9 SDK
Используйте модуль @firebase/rules-unit-testing
для взаимодействия с эмулятором, который работает локально. Если вы получаете тайм-ауты или ошибки ECONNREFUSED
, еще раз проверьте, действительно ли эмулятор запущен.
Мы настоятельно рекомендуем использовать последнюю версию Node.js, чтобы вы могли использовать нотацию async/await
. Почти все поведение, которое вы, возможно, захотите протестировать, включает в себя асинхронные функции, а модуль тестирования предназначен для работы с кодом на основе Promise.
Библиотека модульного тестирования правил v9 всегда знает об эмуляторах и никогда не затрагивает ваши производственные ресурсы.
Вы импортируете библиотеку с помощью модульных операторов импорта версии 9. Например:
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.
После импорта реализация модульных тестов включает в себя:
- Создание и настройка
RulesTestEnvironment
с вызовомinitializeTestEnvironment
. - Настройка тестовых данных без запуска Rules , используя удобный метод, позволяющий временно их обходить,
RulesTestEnvironment.withSecurityRulesDisabled
. - Настройка набора тестов и перехватчиков до/после каждого теста с вызовами для очистки тестовых данных и среды, например
RulesTestEnvironment.cleanup()
илиRulesTestEnvironment.clearFirestore()
. - Реализация тестовых случаев, имитирующих состояния аутентификации, с использованием
RulesTestEnvironment.authenticatedContext
иRulesTestEnvironment.unauthenticatedContext
.
Общие методы и служебные функции
Также см. методы тестирования, специфичные для эмулятора, с использованием модульного API .
initializeTestEnvironment() => RulesTestEnvironment
Эта функция инициализирует тестовую среду для модульного тестирования правил. Сначала вызовите эту функцию для настройки теста. Для успешного выполнения необходимо, чтобы эмуляторы были запущены.
Функция принимает необязательный объект, определяющий TestEnvironmentConfig
, который может состоять из идентификатора проекта и параметров конфигурации эмулятора.
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()
Запустите функцию настройки теста с контекстом, который ведет себя так, как если бы правила безопасности были отключены.
Этот метод принимает функцию обратного вызова, которая принимает контекст обхода правил безопасности и возвращает обещание. Контекст будет уничтожен, как только обещание будет разрешено/отклонено.
RulesTestEnvironment.cleanup()
Этот метод уничтожает все RulesTestContexts
, созданные в тестовой среде, и очищает базовые ресурсы, обеспечивая чистый выход.
Этот метод никак не меняет состояние эмуляторов. Чтобы сбросить данные между тестами, используйте метод очистки данных, специфичный для эмулятора приложения.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Это служебная функция тестового примера.
Функция утверждает, что предоставленное обещание, обертывающее операцию эмулятора, будет разрешено без нарушений правил безопасности.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Это служебная функция тестового примера.
Функция утверждает, что предоставленное обещание, обертывающее операцию эмулятора, будет отклонено с нарушением правил безопасности.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Методы, специфичные для эмулятора
Также ознакомьтесь с распространенными методами тестирования и служебными функциями с использованием модульного API .
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
Этот метод очищает данные в базе данных Firestore, принадлежащие идентификатору projectId
, настроенному для эмулятора Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Этот метод получает экземпляр Firestore для этого тестового контекста. Возвращенный экземпляр Firebase JS Client SDK можно использовать с API-интерфейсами клиентского SDK (модульным или совместимым с v9).
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Этот метод очищает данные в Realtime Database , принадлежащие идентификатору projectId
, настроенному для эмулятора Realtime Database .
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Получите экземпляр Realtime Database для этого тестового контекста. Возвращенный экземпляр Firebase JS Client SDK можно использовать с API-интерфейсами клиентского SDK (модульными или в пространстве имен, версии 9 или выше). Метод принимает URL-адрес экземпляра базы данных реального времени. Если указано, возвращает экземпляр эмулируемой версии пространства имен с параметрами, извлеченными из URL-адреса.
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
Этот метод очищает объекты и метаданные в сегментах хранилища, принадлежащих идентификатору projectId
, настроенному для эмулятора Cloud Storage .
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Этот метод возвращает экземпляр хранилища, настроенный для подключения к эмулятору. Этот метод принимает URL-адрес gs://
в сегменте хранилища Firebase для тестирования. Если указано, возвращает экземпляр хранилища для эмулируемой версии имени сегмента.
Запускайте локальные модульные тесты с помощью JavaScript SDK v8.
Выберите продукт, чтобы увидеть методы, используемые Firebase Test SDK для взаимодействия с эмулятором.
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной аутентификации, указанным в параметрах. Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
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
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
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально работающую базу данных. Принимает объект параметров, который определяет ваше «имя базы данных» и ваши «правила» в виде строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени сегмента хранилища и переопределению переменной аутентификации, указанной в параметрах.
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» и ваши «правила» в виде строк.
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());
API библиотеки RUT для JS SDK v8
Выберите продукт, чтобы увидеть методы, используемые Firebase Test SDK для взаимодействия с эмулятором.
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной аутентификации, указанным в параметрах. Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
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
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
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально работающую базу данных. Принимает объект параметров, который определяет ваше «имя базы данных» и ваши «правила» в виде строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени сегмента хранилища и переопределению переменной аутентификации, указанной в параметрах.
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» и ваши «правила» в виде строк.
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());
Firebase Local Emulator Suite упрощает полную проверку функций и поведения вашего приложения. Это также отличный инструмент для проверки настроек Firebase Security Rules . Используйте эмуляторы Firebase для запуска и автоматизации модульных тестов в локальной среде. Методы, изложенные в этом документе, должны помочь вам при создании и автоматизации модульных тестов для вашего приложения, проверяющих ваши Rules .
Если вы еще этого не сделали, настройте эмуляторы Firebase .
Прежде чем запустить эмулятор
Прежде чем начать использовать эмулятор, имейте в виду следующее:
- Эмулятор первоначально загрузит правила, указанные в поле
firestore.rules
илиstorage.rules
вашего файлаfirebase.json
. Если файл не существует и вы не используете методloadFirestoreRules
илиloadStorageRules
, как описано ниже, эмулятор рассматривает все проекты как имеющие открытые правила. - Хотя большинство SDK Firebase работают с эмуляторами напрямую, только библиотека
@firebase/rules-unit-testing
поддерживает имитациюauth
в правилах безопасности, что значительно упрощает модульные тесты. Кроме того, библиотека поддерживает несколько функций, специфичных для эмулятора, таких как очистка всех данных, как указано ниже. - Эмуляторы также будут принимать производственные токены Firebase Auth, предоставленные через клиентские SDK, и соответствующим образом оценивать правила, что позволяет подключать ваше приложение напрямую к эмуляторам при интеграции и ручных тестах.
Отличия эмуляторов баз данных от продакшена
- Вам не нужно явно создавать экземпляр базы данных. Эмулятор автоматически создаст любой экземпляр базы данных, к которому осуществляется доступ.
- Каждая новая база данных запускается с закрытыми правилами, поэтому пользователи, не являющиеся администраторами, не смогут читать или писать.
- Каждая эмулируемая база данных применяет ограничения и квоты плана Spark (в частности, это ограничивает каждый экземпляр 100 одновременными подключениями).
- Любая база данных примет строку
"owner"
в качестве токена аутентификации администратора. - Эмуляторы в настоящее время не взаимодействуют с другими продуктами Firebase. Примечательно, что обычный поток аутентификации Firebase не работает. Вместо этого вы можете использовать метод
initializeTestApp()
в библиотекеrules-unit-testing
, который принимает полеauth
. Объект Firebase, созданный с помощью этого метода, ведет себя так, как будто он успешно прошел аутентификацию как любой предоставленный вами объект. Если вы передадитеnull
, он будет вести себя как неаутентифицированный пользователь (например, правилаauth != null
не будут работать).
Взаимодействие с эмулятором Realtime Database
Экземпляр 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>
Запускайте локальные модульные тесты с помощью JavaScript SDK версии 9.
Firebase распространяет библиотеку модульного тестирования правил безопасности как с SDK JavaScript версии 9, так и с SDK версии 8. API библиотеки существенно отличаются. Мы рекомендуем библиотеку тестирования v9, которая более оптимизирована и требует меньше настроек для подключения к эмуляторам и, таким образом, позволяет безопасно избежать случайного использования производственных ресурсов. В целях обратной совместимости мы продолжаем делать доступной библиотеку тестирования v8 .
- Общие методы тестирования и служебные функции в SDK версии 9.
- Методы тестирования, специфичные для эмулятора, в v9 SDK
Используйте модуль @firebase/rules-unit-testing
для взаимодействия с эмулятором, который работает локально. Если вы получаете тайм-ауты или ошибки ECONNREFUSED
, еще раз проверьте, действительно ли эмулятор запущен.
Мы настоятельно рекомендуем использовать последнюю версию Node.js, чтобы вы могли использовать нотацию async/await
. Почти все поведение, которое вы, возможно, захотите протестировать, включает в себя асинхронные функции, а модуль тестирования предназначен для работы с кодом на основе Promise.
Библиотека модульного тестирования правил v9 всегда знает об эмуляторах и никогда не затрагивает ваши производственные ресурсы.
Вы импортируете библиотеку с помощью модульных операторов импорта версии 9. Например:
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.
После импорта реализация модульных тестов включает в себя:
- Создание и настройка
RulesTestEnvironment
с вызовомinitializeTestEnvironment
. - Настройка тестовых данных без запуска Rules с использованием удобного метода, позволяющего временно их обходить,
RulesTestEnvironment.withSecurityRulesDisabled
. - Настройка набора тестов и перехватчиков до/после каждого теста с вызовами для очистки тестовых данных и среды, например
RulesTestEnvironment.cleanup()
илиRulesTestEnvironment.clearFirestore()
. - Реализация тестовых случаев, имитирующих состояния аутентификации, с использованием
RulesTestEnvironment.authenticatedContext
иRulesTestEnvironment.unauthenticatedContext
.
Общие методы и служебные функции
Также см. методы тестирования, специфичные для эмулятора, с использованием модульного API .
initializeTestEnvironment() => RulesTestEnvironment
Эта функция инициализирует тестовую среду для модульного тестирования правил. Сначала вызовите эту функцию для настройки теста. Для успешного выполнения необходимо, чтобы эмуляторы были запущены.
Функция принимает необязательный объект, определяющий TestEnvironmentConfig
, который может состоять из идентификатора проекта и параметров конфигурации эмулятора.
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()
Запустите функцию настройки теста с контекстом, который ведет себя так, как если бы правила безопасности были отключены.
Этот метод принимает функцию обратного вызова, которая принимает контекст обхода правил безопасности и возвращает обещание. Контекст будет уничтожен, как только обещание будет разрешено/отклонено.
RulesTestEnvironment.cleanup()
Этот метод уничтожает все RulesTestContexts
, созданные в тестовой среде, и очищает базовые ресурсы, обеспечивая чистый выход.
Этот метод никак не меняет состояние эмуляторов. Чтобы сбросить данные между тестами, используйте метод очистки данных, специфичный для эмулятора приложения.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Это служебная функция тестового примера.
Функция утверждает, что предоставленное обещание, обертывающее операцию эмулятора, будет разрешено без нарушений правил безопасности.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Это служебная функция тестового примера.
Функция утверждает, что предоставленное обещание, обертывающее операцию эмулятора, будет отклонено с нарушением правил безопасности.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Методы, специфичные для эмулятора
Также ознакомьтесь с распространенными методами тестирования и служебными функциями с использованием модульного API .
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
Этот метод очищает данные в базе данных Firestore, принадлежащие идентификатору projectId
, настроенному для эмулятора Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Этот метод получает экземпляр Firestore для этого тестового контекста. Возвращенный экземпляр Firebase JS Client SDK можно использовать с API-интерфейсами клиентского SDK (модульным или совместимым с v9).
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Этот метод очищает данные в Realtime Database , принадлежащие идентификатору projectId
, настроенному для эмулятора Realtime Database .
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Получите экземпляр Realtime Database для этого тестового контекста. Возвращенный экземпляр Firebase JS Client SDK можно использовать с API-интерфейсами клиентского SDK (модульными или в пространстве имен, версии 9 или выше). Метод принимает URL-адрес экземпляра базы данных реального времени. Если указано, возвращает экземпляр эмулируемой версии пространства имен с параметрами, извлеченными из URL-адреса.
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
Этот метод очищает объекты и метаданные в сегментах хранилища, принадлежащих идентификатору projectId
, настроенному для эмулятора Cloud Storage .
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Этот метод возвращает экземпляр хранилища, настроенный для подключения к эмулятору. Этот метод принимает URL-адрес gs://
в сегменте хранилища Firebase для тестирования. Если указано, возвращает экземпляр хранилища для эмулируемой версии имени сегмента.
Запускайте локальные модульные тесты с помощью JavaScript SDK v8.
Выберите продукт, чтобы увидеть методы, используемые Firebase Test SDK для взаимодействия с эмулятором.
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной аутентификации, указанным в параметрах. Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
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
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
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально работающую базу данных. Принимает объект параметров, который определяет ваше «имя базы данных» и ваши «правила» в виде строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени сегмента хранилища и переопределению переменной аутентификации, указанной в параметрах.
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» и ваши «правила» в виде строк.
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());
API библиотеки RUT для JS SDK v8
Выберите продукт, чтобы увидеть методы, используемые Firebase Test SDK для взаимодействия с эмулятором.
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной аутентификации, указанным в параметрах. Используйте это, чтобы создать приложение, аутентифицированное как конкретный пользователь, для использования в тестах.
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
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
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально работающую базу данных. Принимает объект параметров, который определяет ваше «имя базы данных» и ваши «правила» в виде строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени ведра хранилища и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени ведра хранилища, указанного в опциях. Это приложение обходит правила безопасности при чтении и написании в ведро.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашего ведра хранилища.
Отправляет правила местному управлению ведрами хранения. Принимает объект «Параметры», который определяет ваше «хранилище» и ваши «правила» как строки.
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());
Firebase Local Emulator Suite облегчает полную проверку функций и поведения вашего приложения. Это также отличный инструмент для проверки ваших конфигураций Firebase Security Rules . Используйте эмуляторы Firebase для запуска и автоматизации модульных тестов в локальной среде. Методы, изложенные в этом документе, должны помочь вам при создании и автоматизации модульных тестов для вашего приложения, которое подтверждает ваши Rules .
Если вы еще этого не сделали, настройте эмуляторы Firebase .
Прежде чем запустить эмулятор
Прежде чем начать использовать эмулятор, имейте в виду следующее:
- Эмулятор первоначально загрузит правила, указанные в поле
firestore.rules
илиstorage.rules
в вашем файлеfirebase.json
. Если файл не существует, и вы не используете методloadFirestoreRules
илиloadStorageRules
, как описано ниже, эмулятор рассматривает все проекты как наличие открытых правил. - В то время как большинство SDK Firebase работают напрямую с эмуляторами напрямую, только библиотека
@firebase/rules-unit-testing
поддерживающая насмешливуюauth
в правилах безопасности, что делает модульные тесты намного проще. Кроме того, библиотека поддерживает несколько функций, специфичных для эмулятора, таких как очистка всех данных, как указано ниже. - Эмуляторы также примут токены Auth Auth Production Base, предоставляемые через SDK клиента, и соответственно оценивать правила, что позволяет подключать ваше приложение непосредственно к эмуляторам в области интеграции и ручных тестов.
Различия между эмуляторами базы данных и производством
- Вам не нужно явно создавать экземпляр базы данных. Эмулятор автоматически создаст любой экземпляр базы данных, к которому доступ.
- Каждая новая база данных начинается с закрытых правил, поэтому пользователи, не являющиеся админ, не смогут читать или писать.
- Каждая эмулированная база данных применяет пределы плана Spark и квоты (в частности, это ограничивает каждый экземпляр 100 параллельных соединений).
- Любая база данных примет строку
"owner"
в качестве токена администратора. - В настоящее время эмуляторы не имеют рабочего взаимодействия с другими продуктами Firebase. Примечательно, что нормальный поток аутентификации Firebase не работает. Вместо этого вы можете использовать метод
initializeTestApp()
в библиотеке,rules-unit-testing
, которая занимает полеauth
. Объект Firebase, созданный с использованием этого метода, ведет себя так, как если бы он успешно провел подлинность как любую сущность, которую вы предоставляете. Если вы пройдете вnull
, он будет вести себя как несаутентированный пользователь (например,auth != null
правила не пройдут).
Взаимодействие с эмулятором Realtime Database
Экземпляр Realtime Database производственной базы доступен в поддоде firebaseio.com
, и вы можете получить доступ к API REST, как это:
https://<database_name>.firebaseio.com/path/to/my/data.json
Эмулятор работает локально и доступен в localhost:9000
. Чтобы взаимодействовать с конкретным экземпляром базы данных, вам нужно будет использовать параметр запроса ns
, чтобы указать имя базы данных.
http://localhost:9000/path/to/my/data.json?ns=<database_name>
Запустите локальные модульные тесты с Javascript SDK версии 9
Firebase распространяет библиотеку тестирования подразделений по правилам безопасности как с JavaScript SDK версии 9, так и с ее версией 8 SDK. Библиотечные API значительно отличаются. Мы рекомендуем библиотеку тестирования V9, которая является более оптимизированной и требует меньшей настройки для подключения к эмуляторам и, следовательно, безопасно избегать случайного использования производственных ресурсов. Для обратной совместимости мы продолжаем предоставлять библиотеку тестирования V8 .
Используйте модуль @firebase/rules-unit-testing
чтобы взаимодействовать с эмулятором, который работает локально. Если вы получаете тайм-ауты или ошибки ECONNREFUSED
, дважды проверьте, что эмулятор фактически работает.
Мы настоятельно рекомендуем использовать недавнюю версию node.js, чтобы вы могли использовать async/await
Notation. Почти все поведение, которое вы, возможно, захотите протестировать, связано с асинхронными функциями, а модуль тестирования предназначен для работы с кодом на основе перспективных работ.
Библиотека тестирования правил правил V9 всегда осведомлена об эмуляторах и никогда не касается ваших производственных ресурсов.
Вы импортируете библиотеку, используя модульные операторы модульного импорта 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.
После импорта реализация модульных тестов включает в себя:
- Создание и настройка
RulesTestEnvironment
с вызовомinitializeTestEnvironment
. - Настройка тестовых данных без запуска Rules , используя удобный метод, который позволяет временно обходить их,
RulesTestEnvironment.withSecurityRulesDisabled
. - Настройка тестового пакета и за тест до/после крючков с вызовами для очистки данных и среды тестирования, таких как
RulesTestEnvironment.cleanup()
илиRulesTestEnvironment.clearFirestore()
. - Реализация тестовых случаев, которые имитируют состояния аутентификации с использованием
RulesTestEnvironment.authenticatedContext
иRulesTestEnvironment.unauthenticatedContext
.
Общие методы и функции полезности
Также см. Эмуляторные методы испытаний с использованием модульного API .
initializeTestEnvironment() => RulesTestEnvironment
Эта функция инициализирует тестовую среду для тестирования правил. Сначала вызовите эту функцию для настройки тестирования. Успешное исполнение требует, чтобы эмуляторы работали.
Функция принимает дополнительный объект, определяющий TestEnvironmentConfig
, который может состоять из идентификатора проекта и настройки конфигурации эмулятора.
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 Auth.
Используйте возвращаемый объект контекста тестирования в ваших тестах, чтобы получить доступ к любым настроенным экземплярам эмулятора, включая настройки с помощью 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()
Запустите функцию настройки теста с контекстом, который ведет себя так, как будто правила безопасности отключены.
Этот метод принимает функцию обратного вызова, которая принимает контекст, обеспечивающий правила безопасности и дает обещание. Контекст будет уничтожен, как только обещание разрешит / отклонится.
RulesTestEnvironment.cleanup()
Этот метод разрушает все RulesTestContexts
, созданные в тестовой среде, и очищает базовые ресурсы, позволяя чистый выход.
Этот метод никоим образом не меняет состояние эмуляторов. Чтобы сбросить данные между тестами, используйте метод прозрачных данных, специфичный для эмулятора приложения.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Это тестовая функция утилиты.
Функция утверждает, что предоставленное обещание обертывания операции эмулятора будет разрешено без нарушений правил безопасности.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Это тестовая функция утилиты.
Функция утверждает, что предоставленное обещание обертывания операции эмулятора будет отклонено с нарушением правил безопасности.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Эмуляторные методы
Также см. Общие методы испытаний и функции полезности с использованием модульного API .
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
Этот метод очищает данные в базе данных Firestore, которая принадлежит projectId
настроенному для эмулятора Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Этот метод получает экземпляр Firestore для этого теста. Возвращенный экземпляр SDK Client Firebase JS может использоваться с клиентскими API SDK (V9 Modular или V9 Compat).
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Этот метод очищает данные в Realtime Database , которая принадлежит projectId
настроенному для эмулятора Realtime Database .
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Получите экземпляр Realtime Database для этого контекста теста. Возвращенный экземпляр SDK Client Firebase JS может использоваться с клиентскими API SDK (модульная или сменная, версия 9 или более). Метод принимает URL -адрес экземпляра базы данных в реальном времени. Если указано, возвращает экземпляр для эмулированной версии пространства имен с параметрами, извлеченными из URL.
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
Этот метод очищает объекты и метаданные в ведрах для хранения, принадлежащих projectId
, настроенному для эмулятора Cloud Storage .
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Этот метод возвращает экземпляр хранения, настроенный для подключения к эмулятору. Метод принимает gs://
url в ведро для хранения пожарной базы для тестирования. Если указано, возвращает экземпляр хранения для эмулированной версии имени ведра.
Запустите локальные модульные тесты с V8 JavaScript SDK
Выберите продукт, чтобы увидеть методы, используемые SDK Test Firebase для взаимодействия с эмулятором.
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной авторизации, указанной в параметрах. Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Этот метод возвращает инициализированное приложение Admin 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
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени базы данных и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени базы данных, указанного в параметрах. Это приложение обходит правила безопасности при чтении и написании в базу данных.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально запущенную базу данных. Принимает объект «Параметры», который определяет ваше «база данных» и ваши «правила» в качестве строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени ведра хранилища и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени ведра хранилища, указанного в опциях. Это приложение обходит правила безопасности при чтении и написании в ведро.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашего ведра хранилища.
Отправляет правила местному управлению ведрами хранения. Принимает объект «Параметры», который определяет ваше «хранилище» и ваши «правила» как строки.
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());
API библиотеки RUT для JS SDK V8
Выберите продукт, чтобы увидеть методы, используемые SDK Test Firebase для взаимодействия с эмулятором.
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной авторизации, указанной в параметрах. Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Этот метод возвращает инициализированное приложение Admin 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
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени базы данных и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени базы данных, указанного в параметрах. Это приложение обходит правила безопасности при чтении и написании в базу данных.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально запущенную базу данных. Принимает объект «Параметры», который определяет ваше «база данных» и ваши «правила» в качестве строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени ведра хранилища и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени ведра хранилища, указанного в опциях. Это приложение обходит правила безопасности при чтении и написании в ведро.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашего ведра хранилища.
Отправляет правила местному управлению ведрами хранения. Принимает объект «Параметры», который определяет ваше «хранилище» и ваши «правила» как строки.
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());
Firebase Local Emulator Suite облегчает полную проверку функций и поведения вашего приложения. Это также отличный инструмент для проверки ваших конфигураций Firebase Security Rules . Используйте эмуляторы Firebase для запуска и автоматизации модульных тестов в локальной среде. Методы, изложенные в этом документе, должны помочь вам при создании и автоматизации модульных тестов для вашего приложения, которое подтверждает ваши Rules .
Если вы еще этого не сделали, настройте эмуляторы Firebase .
Прежде чем запустить эмулятор
Прежде чем начать использовать эмулятор, имейте в виду следующее:
- Эмулятор первоначально загрузит правила, указанные в поле
firestore.rules
илиstorage.rules
в вашем файлеfirebase.json
. Если файл не существует, и вы не используете методloadFirestoreRules
илиloadStorageRules
, как описано ниже, эмулятор рассматривает все проекты как наличие открытых правил. - В то время как большинство SDK Firebase работают напрямую с эмуляторами напрямую, только библиотека
@firebase/rules-unit-testing
поддерживающая насмешливуюauth
в правилах безопасности, что делает модульные тесты намного проще. Кроме того, библиотека поддерживает несколько функций, специфичных для эмулятора, таких как очистка всех данных, как указано ниже. - Эмуляторы также примут токены Auth Auth Production Base, предоставляемые через SDK клиента, и соответственно оценивать правила, что позволяет подключать ваше приложение непосредственно к эмуляторам в области интеграции и ручных тестов.
Различия между эмуляторами базы данных и производством
- Вам не нужно явно создавать экземпляр базы данных. Эмулятор автоматически создаст любой экземпляр базы данных, к которому доступ.
- Каждая новая база данных начинается с закрытых правил, поэтому пользователи, не являющиеся админ, не смогут читать или писать.
- Каждая эмулированная база данных применяет пределы плана Spark и квоты (в частности, это ограничивает каждый экземпляр 100 параллельных соединений).
- Любая база данных примет строку
"owner"
в качестве токена администратора. - В настоящее время эмуляторы не имеют рабочего взаимодействия с другими продуктами Firebase. Примечательно, что нормальный поток аутентификации Firebase не работает. Вместо этого вы можете использовать метод
initializeTestApp()
в библиотеке,rules-unit-testing
, которая занимает полеauth
. Объект Firebase, созданный с использованием этого метода, ведет себя так, как если бы он успешно провел подлинность как любую сущность, которую вы предоставляете. Если вы пройдете вnull
, он будет вести себя как несаутентированный пользователь (например,auth != null
правила не пройдут).
Взаимодействие с эмулятором Realtime Database
Экземпляр Realtime Database производственной базы доступен в поддоде firebaseio.com
, и вы можете получить доступ к API REST, как это:
https://<database_name>.firebaseio.com/path/to/my/data.json
Эмулятор работает локально и доступен в localhost:9000
. Чтобы взаимодействовать с конкретным экземпляром базы данных, вам нужно будет использовать параметр запроса ns
, чтобы указать имя базы данных.
http://localhost:9000/path/to/my/data.json?ns=<database_name>
Запустите локальные модульные тесты с Javascript SDK версии 9
Firebase распространяет библиотеку тестирования подразделений по правилам безопасности как с JavaScript SDK версии 9, так и с ее версией 8 SDK. Библиотечные API значительно отличаются. Мы рекомендуем библиотеку тестирования V9, которая является более оптимизированной и требует меньшей настройки для подключения к эмуляторам и, следовательно, безопасно избегать случайного использования производственных ресурсов. Для обратной совместимости мы продолжаем предоставлять библиотеку тестирования V8 .
Используйте модуль @firebase/rules-unit-testing
чтобы взаимодействовать с эмулятором, который работает локально. Если вы получаете тайм-ауты или ошибки ECONNREFUSED
, дважды проверьте, что эмулятор фактически работает.
Мы настоятельно рекомендуем использовать недавнюю версию node.js, чтобы вы могли использовать async/await
Notation. Почти все поведение, которое вы, возможно, захотите протестировать, связано с асинхронными функциями, а модуль тестирования предназначен для работы с кодом на основе перспективных работ.
Библиотека тестирования правил правил V9 всегда осведомлена об эмуляторах и никогда не касается ваших производственных ресурсов.
Вы импортируете библиотеку, используя модульные операторы модульного импорта 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.
После импорта реализация модульных тестов включает в себя:
- Создание и настройка
RulesTestEnvironment
с вызовомinitializeTestEnvironment
. - Настройка тестовых данных без запуска Rules , используя удобный метод, который позволяет временно обходить их,
RulesTestEnvironment.withSecurityRulesDisabled
. - Настройка тестового пакета и за тест до/после крючков с вызовами для очистки данных и среды тестирования, таких как
RulesTestEnvironment.cleanup()
илиRulesTestEnvironment.clearFirestore()
. - Реализация тестовых случаев, которые имитируют состояния аутентификации с использованием
RulesTestEnvironment.authenticatedContext
иRulesTestEnvironment.unauthenticatedContext
.
Общие методы и функции полезности
Также см. Эмуляторные методы испытаний с использованием модульного API .
initializeTestEnvironment() => RulesTestEnvironment
Эта функция инициализирует тестовую среду для тестирования правил. Сначала вызовите эту функцию для настройки тестирования. Успешное исполнение требует, чтобы эмуляторы работали.
Функция принимает дополнительный объект, определяющий TestEnvironmentConfig
, который может состоять из идентификатора проекта и настройки конфигурации эмулятора.
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 Auth.
Используйте возвращаемый объект контекста тестирования в ваших тестах, чтобы получить доступ к любым настроенным экземплярам эмулятора, включая настройки с помощью 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()
Запустите функцию настройки теста с контекстом, который ведет себя так, как будто правила безопасности отключены.
Этот метод принимает функцию обратного вызова, которая принимает контекст, обеспечивающий правила безопасности и дает обещание. Контекст будет уничтожен, как только обещание разрешит / отклонится.
RulesTestEnvironment.cleanup()
Этот метод разрушает все RulesTestContexts
, созданные в тестовой среде, и очищает базовые ресурсы, позволяя чистый выход.
Этот метод никоим образом не меняет состояние эмуляторов. Чтобы сбросить данные между тестами, используйте метод прозрачных данных, специфичный для эмулятора приложения.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Это тестовая функция утилиты.
Функция утверждает, что предоставленное обещание обертывания операции эмулятора будет разрешено без нарушений правил безопасности.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Это тестовая функция утилиты.
Функция утверждает, что предоставленное обещание обертывания операции эмулятора будет отклонено с нарушением правил безопасности.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Эмуляторные методы
Также см. Общие методы испытаний и функции полезности с использованием модульного API .
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
Этот метод очищает данные в базе данных Firestore, которая принадлежит projectId
настроенному для эмулятора Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Этот метод получает экземпляр Firestore для этого теста. Возвращенный экземпляр SDK Client Firebase JS может использоваться с клиентскими API SDK (V9 Modular или V9 Compat).
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Этот метод очищает данные в Realtime Database , которая принадлежит projectId
настроенному для эмулятора Realtime Database .
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Получите экземпляр Realtime Database для этого контекста теста. Возвращенный экземпляр SDK Client Firebase JS может использоваться с клиентскими API SDK (модульная или сменная, версия 9 или более). Метод принимает URL -адрес экземпляра базы данных в реальном времени. Если указано, возвращает экземпляр для эмулированной версии пространства имен с параметрами, извлеченными из URL.
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
Этот метод очищает объекты и метаданные в ведрах для хранения, принадлежащих projectId
, настроенному для эмулятора Cloud Storage .
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Этот метод возвращает экземпляр хранения, настроенный для подключения к эмулятору. Метод принимает gs://
url в ведро для хранения пожарной базы для тестирования. Если указано, возвращает экземпляр хранения для эмулированной версии имени ведра.
Запустите локальные модульные тесты с V8 JavaScript SDK
Выберите продукт, чтобы увидеть методы, используемые SDK Test Firebase для взаимодействия с эмулятором.
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной авторизации, указанной в параметрах. Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Этот метод возвращает инициализированное приложение Admin 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
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени базы данных и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени базы данных, указанного в параметрах. Это приложение обходит правила безопасности при чтении и написании в базу данных.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашей базы данных.
Отправляет правила в локально запущенную базу данных. Принимает объект «Параметры», который определяет ваше «база данных» и ваши «правила» в качестве строк.
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
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
Возвращает инициализированное приложение Firebase, соответствующее имени ведра хранилища и переопределению переменной авторизации, указанного в параметрах.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Используйте это для создания приложения, аутентифицированного как администратор для настройки состояния для тестов.
Возвращает инициализированное приложение Admin Firebase, соответствующее имени ведра хранилища, указанного в опциях. Это приложение обходит правила безопасности при чтении и написании в ведро.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Используйте это, чтобы установить правила вашего ведра хранилища.
Отправляет правила местному управлению ведрами хранения. Принимает объект «Параметры», который определяет ваше «хранилище» и ваши «правила» как строки.
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());
API библиотеки RUT для JS SDK V8
Выберите продукт, чтобы увидеть методы, используемые SDK Test Firebase для взаимодействия с эмулятором.
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Этот метод возвращает инициализированное приложение Firebase, соответствующее идентификатору проекта и переменной авторизации, указанной в параметрах. Используйте это для создания приложения, аутентифицированного в качестве конкретного пользователя для использования в тестах.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Этот метод возвращает инициализированное приложение Admin 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
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
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"));
Cloud Storage
initializeTestApp({ storageBucket: 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 storage bucket name and auth variable override specified in options.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: 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 storage bucket name specified in options. This app bypasses security rules when reading and writing to the bucket.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Use this to set your storage bucket's rules.
Sends rules to a locally managed storage buckets. Takes an options object that specifies your "storageBucket" and your "rules" as strings.
firebase
.loadStorageRules({
storageBucket: "my-bucket",
rules: fs.readFileSync("/path/to/storage.rules", "utf8")
});
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 storage bucket read or write fails:
firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());
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 storage bucket read or write succeeds:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());