أثناء إنشاء تطبيقك، قد تحتاج إلى حظر الوصول إلى قاعدة بيانات Cloud Firestore. ومع ذلك، قبل الإطلاق، ستحتاج إلى مزيد من التفاصيل الدقيقة Cloud Firestore Security Rules. باستخدام محاكي Cloud Firestore، بالإضافة إلى إنشاء النماذج الأولية واختبار الميزات والسلوك العام لتطبيقك، يمكنك كتابة اختبارات وحدات تتحقّق من سلوك Cloud Firestore Security Rules.
البدء السريع
وفي ما يتعلّق ببعض حالات الاختبار الأساسية التي تتضمّن قواعد بسيطة، يمكنك تجربة نموذج البدء السريع.
فهم Cloud Firestore Security Rules
نفِّذ Firebase Authentication مع Cloud Firestore Security Rules للاستخدام بدون خادم المصادقة والترخيص والتحقق من صحة البيانات عند استخدام واجهة مكتبات برامج الويب.
تشمل Cloud Firestore Security Rules جزأين:
- عبارة
match
لتحديد المستندات في قاعدة بياناتك - تعبير
allow
يتحكّم في الوصول إلى هذه المستندات
يتحقق Firebase Authentication من صحة بيانات المستخدمين. بيانات اعتماد ويوفر الأساس وأنظمة الوصول القائمة على المستخدم والقائمة على الأدوار.
كل طلب قاعدة بيانات من مكتبة برامج الويب أو الأجهزة الجوّالة في Cloud Firestore يتم تقييمه وفقًا لقواعد الأمان لديك قبل قراءة أي بيانات أو كتابتها. وإذا كانت القواعد تمنع الوصول إلى أي من مسارات المستندات المحددة، فإن قاعدة فشل الطلب.
يمكنك الاطّلاع على مزيد من المعلومات حول Cloud Firestore Security Rules في مقالة بدء استخدام Cloud Firestore Security Rules.
تثبيت المحاكي
لتثبيت المحاكي Cloud Firestore، يمكنك استخدام Firebase CLI. وقم بتشغيل الأمر أدناه:
firebase setup:emulators:firestore
تشغيل المحاكي
ابدأ بإعداد مشروع Firebase في دليل العمل. هذا هو وهي الخطوة الأولى الشائعة عند استخدام واجهة سطر الأوامر في Firebase
firebase init
ابدأ المحاكي باستخدام الأمر التالي. سيتم تشغيل المحاكي حتى تغلق العملية:
firebase emulators:start --only firestore
وفي كثير من الأحيان، تريد بدء تشغيل المحاكي وتشغيل مجموعة تجريبية ثم إغلاق
المحاكي بعد إجراء الاختبارات. يمكنك إجراء ذلك بسهولة باستخدام
الأمر emulators:exec
:
firebase emulators:exec --only firestore "./my-test-script.sh"
عند بدء تشغيل المحاكي، سيحاول تشغيله على منفذ تلقائي (8080). يمكنك
تغيير منفذ المحاكي من خلال تعديل القسم "emulators"
في
ملف firebase.json
:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
قبل تشغيل المحاكي
قبل البدء في استخدام المحاكي، يجب مراعاة ما يلي:
- سيحمّل المحاكي بشكل مبدئي القواعد المحدّدة في
firestore.rules
. الحقل في ملفfirebase.json
. وتتوقّع هذه الميزة اسم ملف محلي يحتوي على Cloud Firestore Security Rules وتطبّق هذه القواعد على جميع المشاريع. إذا لم توفر مسار الملف المحلي أو تستخدم الملف في ما يخصloadFirestoreRules
كما هو موضح أدناه، يتعامل المحاكي مع جميع المشروعات على أنها تحتوي على قواعد مفتوحة. - على الرغم من أنّ
معظم حِزم تطوير البرامج (SDK) لمنصة Firebase
تعمل مع المحاكيات مباشرةً، لا تتيح سوى مكتبة
@firebase/rules-unit-testing
محاكاةauth
في قواعد الأمان، ما يسهّل اختبارات الوحدة كثيرًا. بالإضافة إلى ذلك، تدعم المكتبة بعض الميزات الخاصة بالمحاكي مثل محو جميع البيانات كما هو موضح أدناه. - ستوافق المحاكيات أيضًا على الرموز المميّزة لإصدار الإصدار العلني من Firebase Auth المقدَّمة من خلال حِزم تطوير البرامج (SDK) للعملاء وتقيِّم القواعد وفقًا لذلك، ما يسمح بربط تطبيقك مباشرةً بالمحاكيات في عمليات الدمج والاختبارات اليدوية.
إجراء اختبارات الوحدة المحلية
إجراء اختبارات الوحدات المحلية باستخدام الإصدار 9 من حزمة تطوير البرامج (SDK) لJavaScript
يوزّع Firebase مكتبة اختبارات وحدات قواعد الأمان مع إصدارَيها. 9 JavaScript SDK والإصدار 8 من حزمة تطوير البرامج (SDK) الخاصة بها تساهم واجهات برمجة التطبيقات للمكتبة إلى حد كبير مختلفة. نقترح استخدام مكتبة اختبار الإصدار 9، والتي تكون أكثر سلاسة يتطلّب الأمر إعدادًا أقل للاتصال بالأجهزة المحاكية، وبالتالي يتم تجنُّب العرض غير المقصود بأمان استخدام موارد الإنتاج. وسنواصل توفير مكتبة اختبار الإصدار 8 للحفاظ على التوافق مع الإصدارات القديمة.
- طرق الاختبار الشائعة ووظائف الأداة المساعدة في الإصدار 9 من حزمة تطوير البرامج (SDK)
- طرق الاختبار الخاصة بالمحاكي في حزمة SDK الإصدار 9
استخدام وحدة @firebase/rules-unit-testing
للتفاعل مع المحاكي
التي تعمل محليًا. إذا ظهرت لك أخطاء متعلّقة بانتهاء المهلة أو ECONNREFUSED
أخطاء، يُرجى التحقّق مرة أخرى
حقيقة أن المحاكي قيد التشغيل.
ننصحك بشدة باستخدام إصدار حديث من Node.js لتتمكّن من استخدام
رمز async/await
تقريبًا جميع السلوكيات التي قد ترغب في اختبارها
تتضمن دوال غير متزامنة، وتم تصميم وحدة الاختبار للعمل مع
رمز قائم على التعهدات.
تدرك مكتبة اختبار وحدة القواعد 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
- إعداد بيانات الاختبار بدون تشغيل القواعد، واستخدام الراحة
تسمح لك بتجاوزها مؤقتًا،
RulesTestEnvironment.withSecurityRulesDisabled
- جارٍ إعداد مجموعة الاختبار ولكل اختبار قبل/بعد عناصر المحاذاة مع طلبات استدعاء
تنظيف بيانات الاختبار والبيئة، مثل
RulesTestEnvironment.cleanup()
أوRulesTestEnvironment.clearFirestore()
. - تنفيذ حالات الاختبار التي تحاكي حالات المصادقة باستخدام
RulesTestEnvironment.authenticatedContext
وRulesTestEnvironment.unauthenticatedContext
الطرق الشائعة ووظائف المنفعة
اطّلِع أيضًا على طرق الاختبار الخاصة بالمحاكي في حزمة تطوير البرامج (SDK) من الإصدار 9.
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
، الذي يعمل كرمز مصادق عليه
مستخدم المصادقة. الطلبات التي يتم إنشاؤها من خلال السياق المعروض ستتضمّن نموذجًا تجريبيًا
تم إرفاق الرمز المميّز للمصادقة. يمكنك اختياريًا تمرير عنصر يحدّد المطالبات المخصّصة أو
حمولات بيانات أساسية للرمز المميز للمصادقة.
استخدِم عنصر سياق الاختبار الذي تم عرضه في اختباراتك للوصول إلى أي محاكي.
المثيلات التي تم ضبطها، بما في ذلك الأجهزة التي تم ضبطها باستخدام 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
، الذي يتصرف كعميل
لم يتم تسجيل الدخول عبر المصادقة. لن يتم إرفاق علامات 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>
هذه دالة مساعدة حالة اختبار.
تؤكد الدالة أن Promise المقدمة تعمل على إحاطة عملية المحاكي ستتم حله بدون أي انتهاكات لقواعد الأمان.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
هذه وظيفة أداة لحالة الاختبار.
تؤكد الدالة أن Promise المقدمة تعمل على إحاطة عملية المحاكي سيتم رفضه بسبب انتهاك "قواعد الأمان".
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
الطرق الخاصة بالمحاكي
يُرجى الاطّلاع أيضًا على أساليب الاختبار الشائعة ووظائف الأداة المساعدة في الإصدار 9 من حزمة تطوير البرامج (SDK).
RulesTestEnvironment.clearFirestore() => Promise<void>
تعمل هذه الطريقة على محو البيانات في قاعدة بيانات Firestore التي تنتمي إلى
projectId
الذي تم ضبطه لمحاكي Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
تحصل هذه الطريقة على مثيل Firestore لسياق الاختبار هذا. تم إرجاع يمكن استخدام مثيل حزمة تطوير البرامج (SDK) لعميل JavaScript JS مع واجهات برمجة تطبيقات حزمة تطوير البرامج (SDK) للعميل (الإصدار 9 المكوَّن من وحدات أو v9 compat).
عرض تقييمات القواعد بصريًا
يتيح لك محاكي "Cloud Firestore" عرض طلبات العميل بشكل مرئي واجهة مستخدم مجموعة Emulator، بما في ذلك تتبُّع التقييم لقواعد أمان Firebase.
افتح علامة التبويب Firestore > الطلبات لعرض تسلسل التقييم المفصّل لكل طلب.
إنشاء تقارير الاختبار
بعد إجراء مجموعة من الاختبارات، يمكنك الوصول إلى الاختبار تقارير التغطية التي توضح كيفية تقييم كل قاعدة من قواعد الأمان.
للحصول على التقارير، يمكنك الاستعلام عن نقطة نهاية مكشوفة على المحاكي أثناء إنه قيد التشغيل. للحصول على نسخة متوافقة مع المتصفّحات، استخدِم عنوان URL التالي:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
يقسِّم هذا القواعد إلى تعبيرات وتعبيرات فرعية يمكنك تمرير الماوس لمزيد من المعلومات، بما في ذلك عدد التقييمات والقيم عاد. في ما يتعلّق بإصدار JSON الأولي من هذه البيانات، أدرِج عنوان URL التالي. في استعلامك:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
الاختلافات بين المحاكي والإنتاج
- لست بحاجة إلى إنشاء مشروع Cloud Firestore بشكل صريح. ينشئ المحاكي تلقائيًا أي نسخة يتم الوصول إليها.
- لا يعمل محاكي Cloud Firestore مع مسار Firebase Authentication العادي.
وبدلاً من ذلك، في حزمة تطوير البرامج (SDK) الاختبارية لاختبار Firebase، قدمنا الطريقة
initializeTestApp()
فيrules-unit-testing
، والذي يأخذ الحقلauth
. تم إنشاء اسم حساب Firebase فإن استخدام هذه الطريقة سيعمل كما لو تمت مصادقتها بنجاح وأي كيان تقدمه. إذا نجحت في اجتيازnull
، سيعمل كـ مستخدم لم تتم مصادقته (لن تعمل قواعدauth != null
مثلاً)
تحديد المشاكل المعروفة وحلّها
أثناء استخدام محاكي Cloud Firestore، قد تواجه الصعوبات التالية المعروفة. اتبع الإرشادات أدناه لتحري أي سلوك غير منتظم قمت به وإصلاحها التي يواجهونها. تمت كتابة هذه الملاحظات باستخدام اختبار وحدة "قواعد الأمان" هذه التطبيقات، ولكن يمكن تطبيق الأساليب العامة على أي حزمة تطوير برامج (SDK) لمنصّة Firebase.
سلوك الاختبار غير متسق
إذا كانت اختباراتك تجتاز وتفشل أحيانًا، حتى بدون أي تغييرات على
الاختبارات نفسها، فقد تحتاج إلى التحقق من أنها متسلسلة بشكل صحيح.
تكون معظم التفاعلات مع المحاكي غير متزامنة، لذا تحقق جيدًا من أن جميع
تسلسل التعليمة البرمجية غير المتزامنة بشكل صحيح. يمكنك إصلاح التسلسل عن طريق
أو سلسلة الوعود أو استخدام ترميز await
بكل حرية.
وعلى وجه الخصوص، راجِع العمليات غير المتزامنة التالية:
- إعداد قواعد الأمان، باستخدام
initializeTestEnvironment
مثلاً. - قراءة البيانات وكتابتها باستخدام، مثل
db.collection("users").doc("alice").get()
- تأكيدات التشغيل، بما في ذلك
assertSucceeds
وassertFails
.
تجتاز الاختبارات في المرة الأولى فقط التي يتم فيها تحميل المحاكي
المحاكي في وضع الحالة. يخزن جميع البيانات المكتوبة عليه في الذاكرة، ويتم فقدان أي بيانات عند إيقاف تشغيل المحاكي. إذا كنت تشغّل عدة مقابل نفس معرف المشروع، فيمكن لكل اختبار إنتاج بيانات قد التأثير على الاختبارات اللاحقة. يمكنك استخدام أي من الطرق التالية تجاوز هذا السلوك:
- استخدم معرّفات مشروع فريدة لكل اختبار. يُرجى العلم أنّه إذا اخترت إجراء ذلك،
ستحتاج إلى استدعاء
initializeTestEnvironment
كجزء من كل اختبار، ولا يتم تحميل القواعد تلقائيًا إلا بمعرّف المشروع التلقائي. - إعادة تنظيم الاختبارات حتى لا تتفاعل مع البيانات المكتوبة سابقًا (على سبيل المثال، استخدِم مجموعة مختلفة لكل اختبار).
- حذف جميع البيانات المكتوبة أثناء الاختبار.
عملية الإعداد التجريبية معقّدة للغاية.
عند إعداد الاختبار، قد تحتاج إلى تعديل البيانات بطريقة
Cloud Firestore Security Rules لا يسمحون بذلك فعليًا. إذا كانت قواعدك تطبّق إعداد الاختبار
معقد، جرِّب استخدام RulesTestEnvironment.withSecurityRulesDisabled
في الإعداد
الخطوات، لذلك لن تؤدي عمليات القراءة والكتابة إلى عرض أخطاء PERMISSION_DENIED
.
بعد ذلك، يمكن أن يؤدي الاختبار إلى إجراء العمليات كمشروع تمت مصادقته أو لم تتم مصادقته
مستخدم يستخدم RulesTestEnvironment.authenticatedContext
وunauthenticatedContext
على التوالي. يتيح لك ذلك التحقّق من أنّ Cloud Firestore Security Rules يسمح أو يرفض.
الحالات المختلفة بشكل صحيح.