الفرق بين المراجعتين لصفحة: «ReactNative/testing overview»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
سطر 58: سطر 58:
إذا احتوى الكائن قيد الاختبار على أي اعتماديات، فيجب تزييفه كما هو موضح في الفقرة التالية.
إذا احتوى الكائن قيد الاختبار على أي اعتماديات، فيجب تزييفه كما هو موضح في الفقرة التالية.


ميزة اختبارات الوحدة هي أنها سريعة في الكتابة والتشغيل، لذلك تحصل أثناء عملك على ملاحظات سريعة حول نجاح اختباراتك أو فشلها. يمتلك Jest أيضًا خيارًا لتشغيل الاختبارات ذات الصلة بالشيفرة الذي تعدلها: وضع المشاهدة باستمرار.
ميزة اختبارات الوحدة هي أنها سريعة في الكتابة والتشغيل، لذلك تحصل أثناء عملك على ملاحظات سريعة حول نجاح اختباراتك أو فشلها. يمتلك Jest أيضًا خيارًا لتشغيل الاختبارات ذات الصلة بالشيفرة الذي تعدلها، وهذا الخيار هو [https://jestjs.io/docs/cli#watch Watch mode].
[[ملف:p tests-unit.svg|بديل=tests unit|مركز|تصغير|491x491بك]]
[[ملف:p tests-unit.svg|بديل=tests unit|مركز|تصغير|491x491بك]]
==== التزييف Mocking ====
قد ترغب أحيانًا في تزييف الكائنات المُختبَرة عندما تحتوي على اعتماديات خارجية. "التزييف" هو استبدال جزء من اعتمادية شيفرتك بالتنفيذ الخاص بك.<blockquote>يُعَد استخدام أشياء حقيقية في اختباراتك أفضل من استخدام التزييفات ولكن هناك مواقف لا يكون فيها ذلك ممكنًا، كالحالة التي يعتمد فيها اختبار وحدة JS على وحدة أصيلة مكتوبة بلغة Java أو Objective-C.</blockquote>تخيل أنك تكتب تطبيقًا يعرض الطقس الحالي في مدينتك وأنك تستخدم خدمة خارجية أو اعتمادية أخرى تزودك بمعلومات الطقس. إن أخبرتك الخدمة أن السماء تمطر، فستعرض صورة بها سحابة ممطرة. لا يجب استدعاء هذه الخدمة في اختباراتك للأسباب التالية:
* يمكن أن تبطّئ الاختبارات وتجعلها وغير مستقرة (بسبب طلبات الشبكة المشوَّشة)
* قد تعيد الخدمة بيانات مختلفة في كل مرة تشغّل فيها الاختبار
* يمكن أن تصبح الخدمات الخارجية في وضع عدم الاتصال عندما تحتاج إلى إجراء الاختبارات
لذلك يمكنك توفير تنفيذ خدمة مزيف، واستبدال آلاف سطور الشيفرة وبعض الأجهزة المتصلة بالإنترنت بفعالية<blockquote>يأتي Jest مع [https://jestjs.io/docs/mock-functions#mocking-modules دعم للتزييف] من تزييف مستوى الدالة وصولًا إلى تزييف مستوى الوحدة.</blockquote>
=== اختبارات التكامل Integration Tests ===
يجب أن تتفاعل الأجزاء الفردية مع بعضها البعض عند كتابة أنظمة برمجية أكبر. إذا اعتمدت وحدتك على وحدة أخرى في اختبار الوحدة، فسينتهي بك الأمر في بعض الأحيان إلى تزييف الاعتمادية، واستبدالها باعتمادية أخرى مزيفة.
، تُدمَج الوحدات الفردية الحقيقية (كما هو الحال في تطبيقك) وتُختَبر معًا في اختبار التكامل للتأكد من أنها تتعاون كما هو متوقع. هذا لا يعني أن التزييف لا يحدث هنا، إذ ستظل بحاجة إلى التزييف (مثل تزييف التواصل مع خدمة الطقس)، ولكنك ستحتاج إليه أقل بكثير من اختبار الوحدة.<blockquote>لاحظ أن المصطلحات المتعلقة بما يعنيه اختبار التكامل ليست متناسقة دائمًا، وقد لا يكون الخط الفاصل بين اختبار الوحدة اختبار التكامل واضحًا دائمًا. يندرج اختبارك تحت النوع "اختبار التكامل" إذا كان:
* يجمع بين عدة وحدات من تطبيقك كما هو موضح أعلاه
* يستخدم نظام خارجي
* يستدعي تطبيقًا آخر عبر الشبكة (مثل واجهة برمجة تطبيقات خدمة الطقس)
* يجري أي نوع من أنواع إدخال وإخراج الملفات أو قواعد البيانات
</blockquote>
[[ملف:p tests-integration.svg|بديل=tests integration|مركز|تصغير|527x527بك]]
=== اختبار المكونات Component Tests ===

مراجعة 22:36، 2 يونيو 2021

الاختبار Testing

يمكن أن تتحول الأخطاء الصغيرة التي لا تتوقعها إلى حالات فشل أكبر مع توسع قاعدة الشيفرة، حيث تؤدي الأخطاء إلى تجربة مستخدم سيئة والتي ستؤدي في النهاية خسائر تجارية. تتمثل إحدى طرق منع البرمجة الضعيفة في اختبار شيفرتك قبل إصدارها.

سنغطّي طرقًا آلية مختلفة لضمان عمل تطبيقك كما هو متوقع بدءًا من التحليل الساكن إلى الاختبارات الشاملة.

أهمية عملية الاختبار

نحن بشر والبشر يخطئون. الاختبار مهم لأنه يساعدك في الكشف عن هذه الأخطاء والتحقق من عمل شيفرتك، ويضمن الاختبار استمرار عمل شيفرتك في المستقبل عند إضافة ميزات جديدة، أو إعادة بناء الميزات الموجودة، أو ترقية الاعتماديات الرئيسية لمشروعك.

من أفضل الطرق لإصلاح خطأ في شيفرتك هي كتابة اختبار فاشل يفضح هذا الخطأ، ثم إن نجح هذا الاختبار عند إصلاح الخطأ وإعادة تشغيله، فهذا يعني أن الخطأ قد أُصلِح، ولن يُعاد إدخاله في قاعدة الشيفرة مطلقًا.

يمكن أيضًا أن تكون الاختبارات بمثابة توثيق للأشخاص الجدد الذين ينضمون إلى فريقك، إذ يمكن أن تساعد اختبارات القراءة الأشخاص الذين لم يروا قاعدة بيانات من قبل على فهم كيفية عمل الشيفرة الموجودة.

وأخيرًا، يؤدي إجراء المزيد من الاختبارات الآلية إلى قضاء وقت أقل في عملية ضمان الجودة اليدوية، مما يوفر وقتًا ثمينًا.

التحليل الساكن Static Analysis

تتمثل الخطوة الأولى لتحسين جودة الشيفرة في البدء في استخدام أدوات التحليل الساكنة، إذ يفحص التحليل الساكن شيفرتك بحثًا عن الأخطاء أثناء كتابتها دون تشغيل أي من تلك الشيفرة.

  • تحلّل أدوات Linter الشيفرة للكشف عن الأخطاء الشائعة مثل الشيفرة غير المستخدمة وللمساعدة في تجنب المخاطر، ولإعلام دليلٍ من النمط المحرَّم مثل استخدام مفايتح tab بدلًا من المسافات (أو العكس اعتمادًا على الإعداد الخاص بك).
  • يضمن التحقق من النوع Type checking تطابق البنية التي تمرّرها إلى دالة ما صُمِّمت الدالة لقبوله، كمنع تمرير سلسلة إلى دالة حسابية تقبل أعدادًا.

يأتي إطار عمل React Native مع أداتين من هذا القبيل هما: ESLint للكشف عن الأخطاء و Flow للتحقق من النوع. يمكنك أيضًا استخدام لغة TypeScript، وهي لغة مكتوبة تُصرَّف إلى لغة JavaScript صِرفة.

كتابة شيفرة قابلة للاختبار

تحتاج لبدء الاختبارات أولًا إلى كتابة شيفرةٍ قابلة للاختبار. افترض مثلًا عملية تصنيع الطائرات، حيث يجري اختبار أجزاء الطائرة لضمان أنها آمنة وتعمل بصورةٍ صحيحة قبل إقلاع الطائرة لأول مرة لإثبات أن جميع أنظمتها المعقدة تعمل مع بعضها البعض بصورة جيدة، إذ تُختبَر الأجنحة عن طريق ثنيها تحت حمولة شديدة، وتُختبَر أجزاء المحرك للتأكد من متانتها، ويُختبَر الزجاج الأمامي ضد تأثير محاكاة الطيور.

البرمجيات مشابهة للطائرة، إذ يمكنك كتابة شيفرتك ضمن وحدات صغيرة متعددة بدلًا من كتابة برنامجك بالكامل في ملف ضخم واحد يحتوي على العديد من الأسطر البرمجية، بحيث يمكنك اختبار وحدات الشيفرة اختبارًا أكثر شمولًا من اختبار جميع الشيفرة. تتشابك بهذه الطريقة كتابة الشيفرة القابلة للاختبار مع كتابة شيفرة معيارية دون اخطاء.

يمكنك جعل تطبيقك أكثر قابلية للاختبار من خلال فصل جزء عرض تطبيقك (أو مكونات React) عن منطق عملك وحالة التطبيق (بغض النظر عما إذا استخدمت Redux أو MobX أو حلولًا أخرى). يمكنك باستخدام هذه الطريقة الاحتفاظ باختبار منطق عملك (والذي لا ينبغي أن يعتمد على مكونات React) بصورةٍ مستقلة عن المكونات نفسها، فالهدف الأساسي هو إخراج واجهة مستخدم تطبيقك.

يمكنك الذهاب إلى أبعد من ذلك نظريًا من خلال نقل كل المنطق والبيانات المجلوبة من مكوناتك، وبالتالي ستُخصَّص مكوناتك فقط للإخراج، وستكون حالتك مستقلة تمامًا عن مكوناتك، إذ سيعمل منطق تطبيقك بدون أي مكونات React على الإطلاق.

اختبارات الكتابة

يجب الآن كتابة بعض الاختبارات الفعلية بعد كتابة شيفرة قابلة للاختبار. يُحمَّل قالب React Native الافتراضي مع إطار عمل اختبار Jest، ويشتمل هذا القالب على إعداد مسبق مصمَّم خصيصًا لهذه البيئة حتى تتمكن من زيادة الإنتاجية دون تعديل الإعداد والتزييفات mocks (سنتكلم لاحقًا عن التزييف mocking). يمكنك استخدام Jest لكتابة جميع أنواع الاختبارات.

إن أجريت تطويرًا يعتمد على الاختبار، فيجب كتابة الاختبارات أولًا، وبالتالي تصبح شيفرتك قابلة للاختبار.

بنية الاختبارات

يجب أن تكون اختباراتك قصيرة وتختبر شيئًا واحدًا فقط. لنبدأ بمثال اختبار وحدة مكتوب باستخدام Jest:

it('given a date in the past, colorForDueDate() returns red', () => {
  expect(colorForDueDate('2000-10-20')).toBe('red');
});

يوصَف الاختبار بواسطة السلسلة المُمرَّرة إلى الدالة it. احرص على كتابة الوصف مع توضيح ما تختبره، إذ يجب أن يتضمن الوصف ما يلي:

  1. Given: بعض الشروط المسبقة
  2. When: بعض الإجراءات التي تنفّذها الدالة التي تختبرها
  3. Then: النتيجة المتوقعة

يُعرف ذلك أيضًا باسم AAA (Arrange, Act, Assert).

يقدّم Jest دالة describe للمساعدة في تنظيم اختباراتك. استخدم دالة describe لتجميع جميع الاختبارات التي تنفّذ المهمة نفسها، ويمكن أن تتداخل الأوصاف، إذا كنت بحاجة إلى ذلك. الدوال الأخرى التي ستستخدمها هي beforeEach أو beforeAll التي يمكنك استخدامها لإعداد الكائنات التي تختبرها. اقرأ المزيد في Jest api reference.

إذا كان الاختبار الخاص بك يحتوي على العديد من الخطوات أو التوقعات، فقد تقسّمه إلى عدة خطوات أصغر. تأكد أيضًا من أن اختباراتك مستقلة تمامًا عن بعضها البعض، إذ يجب أن يكون كل اختبار في مجموعتك قابلًا للتنفيذ بمفرده دون إجراء اختبار آخر أولًا. بينما إذا أجريت جميع اختباراتك معًا، فيجب ألا يؤثر الاختبار الأول على خرج الاختبار الثاني.

أخيرًا، يحب المطورون عندما تعمل شيفرتهم دون أخطاء، والعكس صحيح عند تطبيق الاختبارات، فالاختبار الفاشل هو شيء جيد. يخبرنا فشل الاختبار أن هناك شيئًا ما ليس صحيحًا، وهذا يمنحك فرصة لإصلاح المشكلة قبل أن تؤثر على المستخدمين.

اختبارات الوحدة Unit tests

تغطي اختبارات الوحدة أصغر أجزاء الشيفرة، مثل الدوال أو الأصناف الفردية.

إذا احتوى الكائن قيد الاختبار على أي اعتماديات، فيجب تزييفه كما هو موضح في الفقرة التالية.

ميزة اختبارات الوحدة هي أنها سريعة في الكتابة والتشغيل، لذلك تحصل أثناء عملك على ملاحظات سريعة حول نجاح اختباراتك أو فشلها. يمتلك Jest أيضًا خيارًا لتشغيل الاختبارات ذات الصلة بالشيفرة الذي تعدلها، وهذا الخيار هو Watch mode.

tests unit

التزييف Mocking

قد ترغب أحيانًا في تزييف الكائنات المُختبَرة عندما تحتوي على اعتماديات خارجية. "التزييف" هو استبدال جزء من اعتمادية شيفرتك بالتنفيذ الخاص بك.

يُعَد استخدام أشياء حقيقية في اختباراتك أفضل من استخدام التزييفات ولكن هناك مواقف لا يكون فيها ذلك ممكنًا، كالحالة التي يعتمد فيها اختبار وحدة JS على وحدة أصيلة مكتوبة بلغة Java أو Objective-C.

تخيل أنك تكتب تطبيقًا يعرض الطقس الحالي في مدينتك وأنك تستخدم خدمة خارجية أو اعتمادية أخرى تزودك بمعلومات الطقس. إن أخبرتك الخدمة أن السماء تمطر، فستعرض صورة بها سحابة ممطرة. لا يجب استدعاء هذه الخدمة في اختباراتك للأسباب التالية:

  • يمكن أن تبطّئ الاختبارات وتجعلها وغير مستقرة (بسبب طلبات الشبكة المشوَّشة)
  • قد تعيد الخدمة بيانات مختلفة في كل مرة تشغّل فيها الاختبار
  • يمكن أن تصبح الخدمات الخارجية في وضع عدم الاتصال عندما تحتاج إلى إجراء الاختبارات

لذلك يمكنك توفير تنفيذ خدمة مزيف، واستبدال آلاف سطور الشيفرة وبعض الأجهزة المتصلة بالإنترنت بفعالية

يأتي Jest مع دعم للتزييف من تزييف مستوى الدالة وصولًا إلى تزييف مستوى الوحدة.

اختبارات التكامل Integration Tests

يجب أن تتفاعل الأجزاء الفردية مع بعضها البعض عند كتابة أنظمة برمجية أكبر. إذا اعتمدت وحدتك على وحدة أخرى في اختبار الوحدة، فسينتهي بك الأمر في بعض الأحيان إلى تزييف الاعتمادية، واستبدالها باعتمادية أخرى مزيفة.

، تُدمَج الوحدات الفردية الحقيقية (كما هو الحال في تطبيقك) وتُختَبر معًا في اختبار التكامل للتأكد من أنها تتعاون كما هو متوقع. هذا لا يعني أن التزييف لا يحدث هنا، إذ ستظل بحاجة إلى التزييف (مثل تزييف التواصل مع خدمة الطقس)، ولكنك ستحتاج إليه أقل بكثير من اختبار الوحدة.

لاحظ أن المصطلحات المتعلقة بما يعنيه اختبار التكامل ليست متناسقة دائمًا، وقد لا يكون الخط الفاصل بين اختبار الوحدة اختبار التكامل واضحًا دائمًا. يندرج اختبارك تحت النوع "اختبار التكامل" إذا كان:

  • يجمع بين عدة وحدات من تطبيقك كما هو موضح أعلاه
  • يستخدم نظام خارجي
  • يستدعي تطبيقًا آخر عبر الشبكة (مثل واجهة برمجة تطبيقات خدمة الطقس)
  • يجري أي نوع من أنواع إدخال وإخراج الملفات أو قواعد البيانات
tests integration

اختبار المكونات Component Tests