Podczas tworzenia aplikacji możesz zablokować dostęp do swojego Baza danych Cloud Firestore. Jednak przed wdrożeniem potrzebnych jest zgłębianie szczegółów Cloud Firestore Security Rules Oprócz tworzenia prototypów za pomocą emulatora Cloud Firestore oraz testowanie ogólnych funkcji i działania aplikacji, można pisać testy jednostkowe, które sprawdzają działanie Cloud Firestore Security Rules.
Krótkie wprowadzenie
Kilka podstawowych zastosowań testowych z prostymi regułami znajdziesz w krótkim wprowadzeniu.
Poznaj Cloud Firestore Security Rules
Wdróż Firebase Authentication oraz Cloud Firestore Security Rules dla usług bezserwerowych uwierzytelniania, autoryzacji i weryfikacji danych podczas korzystania bibliotek klienta internetowego.
Cloud Firestore Security Rules obejmuje 2 elementy:
- Instrukcja
match
identyfikująca dokumenty w bazie danych. - Wyrażenie
allow
kontrolujące dostęp do tych dokumentów.
Firebase Authentication weryfikuje użytkowników danych logowania i stanowi podstawę systemów dostępu opartych na użytkownikach i rolach.
Każde żądanie bazy danych z biblioteki klienta mobilnego/internetowego Cloud Firestore jest oceniane pod kątem Twoich reguł zabezpieczeń przed odczytaniem lub zapisem danych. Jeśli reguły odmawiają dostępu do dowolnej ze wskazanych ścieżek dokumentów, cała sekwencja nie powiodło się.
Więcej informacji o usłudze Cloud Firestore Security Rules znajdziesz w artykule Pierwsze kroki z Cloud Firestore Security Rules.
Zainstaluj emulator
Aby zainstalować emulator Cloud Firestore, użyj interfejsu wiersza poleceń Firebase i uruchom to polecenie:
firebase setup:emulators:firestore
Uruchamianie emulatora
Zacznij od zainicjowania projektu Firebase w katalogu roboczym. To jest często jest to pierwszy krok podczas korzystania z interfejsu wiersza poleceń Firebase.
firebase init
Uruchom emulator za pomocą tego polecenia. Emulator będzie działać do zakończenia procesu:
firebase emulators:start --only firestore
W wielu przypadkach chcesz uruchomić emulator, uruchomić pakiet testowy, a potem wyłączyć
wyłączyć emulator po przeprowadzeniu testów. Możesz to łatwo zrobić za pomocą
Polecenie emulators:exec
:
firebase emulators:exec --only firestore "./my-test-script.sh"
Po uruchomieniu emulator będzie próbował uruchomić się na porcie domyślnym (8080). Dostępne opcje
zmień port emulatora, modyfikując sekcję "emulators"
swojego
Plik firebase.json
:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
Zanim uruchomisz emulator
Zanim zaczniesz korzystać z emulatora, pamiętaj o tych kwestiach:
- Emulator początkowo wczyta reguły określone w polu
firestore.rules
plikufirebase.json
. Oczekuje ona nazwy lokalnego pliku, który zawiera Cloud Firestore Security Rules, i stosuje te reguły do wszystkich w projektach AI. Jeśli nie podasz lokalnej ścieżki pliku lub użyjeszloadFirestoreRules
, zgodnie z opisem poniżej, emulator traktuje wszystkie projektów z otwartymi regułami. - Choć
większość pakietów SDK Firebase
bezpośrednio obsługiwać emulatory, tylko biblioteka
@firebase/rules-unit-testing
obsługuje naśmiewanie się zauth
w regułach zabezpieczeń, co znacznie ułatwia testowanie jednostkowe. Ponadto obsługuje kilka funkcji emulatorów, takich jak czyszczenie wszystkich danych, jak opisano poniżej. - Emulatory będą też akceptować produkcyjne tokeny uwierzytelniania Firebase udostępnione za pomocą pakietów SDK klienta i odpowiednio oceniać reguły, co umożliwia bezpośrednio do emulatorów w ramach testów integracji i testów ręcznych.
Przeprowadzanie lokalnych testów jednostkowych
Przeprowadzanie lokalnych testów jednostkowych za pomocą pakietu SDK JavaScript w wersji 9
Firebase rozpowszechnia bibliotekę testowania jednostkowego reguł zabezpieczeń wraz z jej wersją SDK 9 JavaScript i jego pakiet SDK w wersji 8. Interfejsy API biblioteki są w znacznym stopniu w inny sposób. Zalecamy korzystanie z biblioteki testowej v9, która jest prostsza w obsłudze wymaga mniej konfiguracji, aby można było łączyć się z emulatorami, i bezpiecznie uniknąć przypadkowego wykorzystanie zasobów produkcyjnych. Aby zapewnić zgodność wsteczną, wprowadzamy dostępna biblioteka do testowania wersji 8.
- Typowe metody testowania i funkcje narzędziowe w pakiecie SDK w wersji 9
- Metody testowe emulatorów w pakiecie SDK w wersji 9
Interakcja z emulatorem za pomocą modułu @firebase/rules-unit-testing
który działa lokalnie. Jeśli wystąpi przekroczenie limitu czasu oczekiwania lub ECONNREFUSED
błąd, sprawdź jeszcze raz
że emulator działa.
Zdecydowanie zalecamy korzystanie z najnowszej wersji środowiska Node.js, co pozwoli Ci korzystać z
Zapis async/await
. Prawie wszystkie zachowania, które warto przetestować
obejmuje funkcje asynchroniczne, a moduł testowania jest przeznaczony do działania
Kod oparty na obietnicy.
Biblioteka testowania jednostkowego w wersji 9 zawsze wie o emulatorach i nigdy zasobów produkcyjnych.
Bibliotekę zaimportujesz za pomocą modułowych instrukcji importowania w wersji 9. Przykład:
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.
Po zaimportowaniu testy jednostkowe obejmują:
- Tworzenie i konfigurowanie obiektu
RulesTestEnvironment
z wywołanieminitializeTestEnvironment
- Konfigurowanie danych testowych bez uruchamiania reguł, korzystając z wygody
która pozwala tymczasowo je ominąć,
RulesTestEnvironment.withSecurityRulesDisabled
- Konfigurowanie pakietu testowego i punktów zaczepienia przed i po każdym teście z wywołaniami
wyczyść dane testowe i środowisko, takie jak
RulesTestEnvironment.cleanup()
lubRulesTestEnvironment.clearFirestore()
. - Wdrażanie przypadków testowych, które naśladują stany uwierzytelniania za pomocą
RulesTestEnvironment.authenticatedContext
iRulesTestEnvironment.unauthenticatedContext
Typowe metody i funkcje użytkowe
Zobacz też metody testowe związane z emulatorami w pakiecie SDK w wersji 9.
initializeTestEnvironment() => RulesTestEnvironment
Ta funkcja inicjuje środowisko testowe do testowania jednostkowego reguł. Zadzwoń dla konfiguracji testu. Aby się udało, emulatory muszą być w domu.
Funkcja akceptuje opcjonalny obiekt definiujący TestEnvironmentConfig
,
który może składać się z identyfikatora projektu i ustawień konfiguracji emulatora.
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
Ta metoda tworzy RulesTestContext
, który działa jak uwierzytelniony
Uwierzytelnianie użytkownika. Żądania utworzone przy użyciu zwróconego kontekstu będą miały model
Dołączono token uwierzytelniania. Opcjonalnie prześlij obiekt definiujący deklaracje niestandardowe lub
zastąpienia dla ładunków tokenów uwierzytelniania.
Użyj zwróconego obiektu kontekstu testowego w testach, aby uzyskać dostęp do dowolnego emulatora
skonfigurowanych instancji, w tym tych ze skonfigurowanych przy użyciu 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
Ta metoda tworzy obiekt RulesTestContext
, który działa jak klient, który jest
Użytkownik nie zalogował się przez Uwierzytelnianie. Żądania utworzone za pomocą zwróconego kontekstu nie będą
tokeny uwierzytelniania Firebase.
Użyj zwróconego obiektu kontekstu testowego w testach, aby uzyskać dostęp do dowolnego emulatora
skonfigurowanych instancji, w tym tych ze skonfigurowanych przy użyciu 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()
Uruchom funkcję konfiguracji testowej z kontekstem, który działa tak, jakby reguły zabezpieczeń wyłączono.
Ta metoda korzysta z funkcji wywołania zwrotnego, która wykorzystuje funkcję omijania reguł zabezpieczeń i zwraca obietnicę. Kontekst zostanie zniszczony, gdy obietnica podejmie decyzję lub ją odrzuci.
RulesTestEnvironment.cleanup()
Ta metoda niszczy wszystkie RulesTestContexts
utworzone w środowisku testowym i
czyści bazowe zasoby, pozostawiając czyste wyjście.
Ta metoda nie zmienia w żaden sposób stanu emulatorów. Resetowanie danych między kolejnymi testami należy użyć metody jasnej danych specyficznej dla emulatora aplikacji.
assertSucceeds(pr: Promise<any>)) => Promise<any>
To jest funkcja narzędziowa przypadku testowego.
Funkcja potwierdza, że podana usługa Promise opakowuje operację emulatora zostanie rozwiązany bez naruszeń reguł zabezpieczeń.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
To jest funkcja narzędziowa przypadku testowego.
Funkcja potwierdza, że podana usługa Promise opakowuje operację emulatora zostanie odrzucona z powodu naruszenia reguł zabezpieczeń.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Metody specyficzne dla emulatora
Zapoznaj się też z typowymi metodami testowania i funkcjami narzędziowymi w pakiecie SDK w wersji 9.
RulesTestEnvironment.clearFirestore() => Promise<void>
Ta metoda usuwa w bazie danych Firestore dane, które należą do
Uprawnienia projectId
zostały skonfigurowane dla emulatora Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Ta metoda pobiera instancję Firestore na potrzeby tego kontekstu testowego. Zwrócone wartości Instancji pakietu SDK Firebase JS Client SDK można używać z interfejsami API pakietu SDK klienta (modułowa wersja 9) lub zgodnego z wersją 9).
Wizualizacja ocen reguł
Emulator Cloud Firestore umożliwia wizualizację żądań klientów w interfejsu użytkownika Pakietu emulatorów, w tym śledzenia oceny dla reguł zabezpieczeń Firebase.
Otwórz Firestore > Prośby, aby wyświetlić szczegółową ocenę. dla każdego żądania.
Generowanie raportów z testów
Po przeprowadzeniu zestawu testów możesz uzyskać dostęp do testów raporty o zasięgu, które pokazują, jak została oceniona każda z Twoich reguł zabezpieczeń.
Aby uzyskać te raporty, wyślij w emulatorze zapytanie do ujawnionego punktu końcowego, podczas gdy jego uruchomienie. W przypadku wersji przeznaczonej do wyświetlania w przeglądarce użyj tego adresu URL:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
Reguły są dzielone na wyrażenia i podwyrażenia, najechanie kursorem myszy, aby uzyskać więcej informacji, w tym liczbę ocen i wartości . W przypadku nieprzetworzonej wersji JSON tych danych dołącz ten adres URL w zapytaniu:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
Różnice między emulatorem a produkcją
- Nie musisz bezpośrednio tworzyć projektu Cloud Firestore. Emulator automatycznie tworzy każdą instancję, do której uzyskano dostęp.
- Emulator Cloud Firestore nie działa w zwykłym procesie Firebase Authentication.
W pakiecie SDK Firebase Test SDK udostępniliśmy metodę
initializeTestApp()
w parametrze Bibliotekarules-unit-testing
, która zajmuje poleauth
. Utworzono nick Firebase używając tej metody, będzie działać tak, jakby została pomyślnie uwierzytelniona jako bez względu na nazwę podmiotu. Jeśli przekażesz zasadęnull
, będzie ona działać jako nieuwierzytelniony użytkownik (na przykład regułyauth != null
zakończą się niepowodzeniem).
Rozwiązywanie znanych problemów
Podczas używania emulatora Cloud Firestore możesz napotkać te znane problemów. Aby rozwiązać problem z nieprawidłowym zachowaniem, postępuj zgodnie z poniższymi wskazówkami z całego świata. Te notatki są tworzone podczas testowania jednostkowego reguł zabezpieczeń ale ogólne podejścia mają zastosowanie do każdego pakietu SDK Firebase.
Działanie testu jest niespójne
Jeśli testy są czasami zaliczone i kończą się niepowodzeniem, nawet jeśli nie wprowadzasz żadnych zmian
podczas samych testów, warto sprawdzić, czy mają prawidłową sekwencję.
Większość interakcji z emulatorem jest asynchroniczna, więc sprawdź dokładnie, czy wszystkie
dla kodu asynchronicznego należy zastosować odpowiednią sekwencję. Możesz poprawić sekwencjonowanie, stosując jedną z tych metod:
łańcuch obietnic lub swobodne korzystanie z notacji await
.
W szczególności sprawdź te operacje asynchroniczne:
- Ustawianie reguł zabezpieczeń, na przykład
initializeTestEnvironment
. - Odczyt i zapis danych, np.
db.collection("users").doc("alice").get()
. - Potwierdzenia działań, w tym
assertSucceeds
iassertFails
.
Testy zaliczają się tylko przy pierwszym wczytaniu emulatora
Emulator jest stanowy. Przechowuje wszystkie zapisane w niej dane w pamięci, wyłączenie emulatora spowoduje utratę danych. Jeśli masz wiele reklam testów z tym samym identyfikatorem projektu, każdy test może dostarczyć dane, które mogą wpłynąć na kolejne testy. Możesz użyć dowolnej z tych metod, aby: omiń to zachowanie:
- W każdym teście używaj unikalnych identyfikatorów projektów. Pamiętaj, że jeśli to zrobisz,
musi wywołać funkcję
initializeTestEnvironment
w ramach każdego testu; reguły są ładowane automatycznie tylko dla domyślnego identyfikatora projektu. - Przeorganizuj testy tak, aby nie wchodziły w interakcje z wcześniej zapisanymi danymi (np. dla każdego testu użyj innej kolekcji).
- Usuń wszystkie dane zapisane podczas testu.
Konfiguracja testu jest bardzo skomplikowana
Podczas konfigurowania testu warto zmodyfikować dane w taki sposób, aby
Cloud Firestore Security Rules nie zezwalają na dostęp. Jeśli reguły powodują konfigurację testu
złożone, spróbuj użyć w konfiguracji usługi RulesTestEnvironment.withSecurityRulesDisabled
kroków, więc odczyty i zapisy nie będą wywoływać błędów PERMISSION_DENIED
.
Po tym czasie test może wykonywać operacje jako uwierzytelniony lub nieuwierzytelniony
użytkownik korzystający z funkcji RulesTestEnvironment.authenticatedContext
i unauthenticatedContext
. Pozwoli Ci to sprawdzić, czy Cloud Firestore Security Rules zezwala / nie zezwala na dostęp
poszczególne przypadki.