مقدمة:

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

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

STLS:

الاختبار هو عملية اكتشاف أكبر عدد ممكن من الأخطاء، وأحد العمليات التي يمكن تطبيقها لتحقيق عملية الاختبار هي STLS، اختصاراً لــ Software Testing Life Cycle، وتتكون هذه العملية من ستة مراحل على الشكل التالي:

1. تحليل المتطلبات: في هذه المرحلة يعمل فريق الاختبار على فهم متطلبات المشروع، وتعد هذه المرحلة مهمة لتجنب فهم غير صحيح للمتطلبات، مما سيؤدي لاحقاً إلى وضع اختبارات غير صالحة.

2.التخطيط للاختبار: في هذه المرحلة يتم وضع خطة اختبار، وتحديد عدة عوامل منها:
a. تحديد نطاق الاختبار، تحديد الوظائف والميزات التي يجب اختبارها والوظائف التي لا يجب اختبارها.
b. تحديد الخصائص التي يجب أن يحققها المشروع والتي يجب اختبارها، مثل الوظائف و الأمان وقابلية الاستخدام.. الخ.
c. توثيق جميع المخرجات التي يتم إنتاجها خلال عملية الاختبار ومنها:

 Test Scenarios .i: وتشمل الحالات المحتملة التي يجب تنفيذها لاختبار البرمجيات، وتصف كيفية تنفيذ الاختبار وما الذي يجب اختبار.  
 Test Cases .ii: وتشمل الخطوات الدقيقة اللازمة لتنفيذ كل حالة اختبار، وتصف بالتفصيل كيفية تنفيذ الاختبار وكيفية تقييم النتائج.
Test Data .iii: وتشمل البيانات المحددة التي يجب استخدامها في الاختبارات، وتشمل المدخلات والمخرجات المتوقعة وأي بيانات أخرى ذات صلة.

3. تطوير حالة الاختبار: في هذه المرحلة يتم كتابة حالات الاختبار التي تم وضعها في مرحلة التخطيط للاختبار.

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

5. تنفيذ الاختبار: في هذه المرحلة يتم التنفيذ، ومراقبة النتائج، وفي حال حدوث خطأ ما، يتم التواصل مع فريق التطوير من أجل حل المشكلة.

6. إنهاء دورة الاختبار: وهي المرحلة الأخيرة في عملية الاختبار، وفيها يتم تحليل وتقييم النتائج.

TDD:

هو اختصار لـ Test Driven Development (التطوير المقاد بالاختبار). وتعني كتابة الاختبارات قبل كتابة الكود الفعلي (الإنتاجي).

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

مراحل الـ TDD:

يتم تطبيق TDD بشكل عام من خلال الخطوات التالية:

1- كتابة اختبار صغير ومحدد لوظيفة معينة.

2- تشغيل الاختبار والتحقق من فشله (red).

3- كتابة الكود اللازم لجعل الاختبار ينجح (الانتقال من red إلى الـ green).

4- تشغيل الاختبار والتحقق من نجاحه (green).

5- تحسين الكود (تنظيف الكود المكرر – تحسين قابلية إعادة الاستخدام.. الخ) (Refactor)

6- تكرار العملية السابقة على حالات أخرى ووظائف أخرى.

مثال عن الـ TDD:

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

في الـ TDD سنقوم أولاً بكتابة حالات الاختبار الخاصة بتابع الجمع (مثلاً عند إدخال الرقمين x1 و x2 نتوقع أن تكون النتيجة هي x3)، ثم سنقوم بكتابة الكود الخاص بهذا الاختبار وسنقوم بعدها بتشغيل هذا الاختبار، النتيجة هنا ستكون هي الفشل (red) لإن منطق الكود الفعلي لم يتم كتابته بعد، ننتقل بعدها إلى الـكود الفعلي ونقوم بكتابة تابع الجمع، وبعد الانتهاء منه نقوم بتشغيل كود الاختبار الذي قمنا بكتابته وهنا سنكون أمام خيارين، إما سينجح الاختبار(green) وعندها ننتقل إلى حالة أخرى، أو سيفشل، وفي تلك الحالة سنقوم بتعديل الكود الفعلي ونعيد اختباره حتى ينجح (يصبح green).

قوانين الـ TDD:

1. لا يسمح لك بكتابة أي كود إنتاجي جديد في التطبيق، ما لم يكن هناك اختبار وحدة (Unit Test) يفشل، وبمعنى آخر، يتعين عليك أولاً كتابة اختبار وحدة يتوقع فشله قبل كتابة أي كود إنتاجي جديد.

2. لا يُسمح لك بكتابة أي اختبار أكثر من اختبار كافٍ للفشل، وتعني أنه لا يمكنك كتابة الكثير من الاختبارات، أي انه إذا قمت بكتابة UNIT TEST ثم قمت بتنفيذها وبعدها فشلت (red) عندها يجب عليك التوقف عن كتابة اختبار جديد.

3. لا يسمح لك بكتابة أي كود فعلي، أكثر من الكود اللازم لاجتياز حالة الفشل.

فوائد الـ TDD:

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

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

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

TDD باستخدام الـ Flutter:

يمكن كتابة حالات الاختبار التي نريد تحقيقها، قبل كتابة الكود الفعلي من خلال الاختبارات التي توفرها الـ Flutter.

نعلم أن أنواع الاختبارات في الـ Flutter هي ثلاثة أنواع (Unit Test – Widget Test – Integration Test) سنتكلم في مقالنا هذا عن ال Unit Test.

Unit test في الـ flutter:

اختبار الوحدة unit test: هو نوع من اختبار البرمجيات والذي يطبق على أصغر وحدة (function, method …).

تمر ال unit test بثلاث مراحل:

Arrange: في هذه المرحلة، يتم إعداد كل ما يلزم لتنفيذ الاختبار، أي إعداد الظروف اللازمة لتنفيذ الاختبار بنجاح، وتهيئة أي قيم أو متغيرات أو مدخلات مطلوبة لتنفيذ الاختبار.

Act: يتم تنفيذ الوحدة المراد اختبارها بناءً على الظروف المعدة في المرحلة السابقة، ويتم تخزين نتيجة تنفيذ الوحدة في متغير محدد لاحقًا للاستخدام في المرحلة الثالثة.

Assert: في هذه المرحلة، يتم التحقق من نتيجة تنفيذ الوحدة ومقارنتها بالنتيجة المتوقعة التي تم إعدادها في المرحلة الأولى، وتتضمن هذه المرحلة استخدام دوال التأكد (Assert functions) للتحقق من صحة النتيجة، والتحقق من حدوث الأحداث المتوقعة، مثل استدعاء دالة محددة، والتأكد من أن الوحدة المختبرة تعمل كما هو متوقع.

مثال:

يوجد كلاس يحوي على دالة increment بحيث نريد أن تقوم هذه الدالة بزيادة قيمة الـ value بمقدار واحد بعد استدعاءها.

سنعتمد في التطوير على الـ TDD وسنقوم بإنشاء ملفين الأول هو counter.dart والثاني هو ملف الـ test وهو counter_test.dart

سيحوي كلاس الـ counter على الدالة التي نريد تطبيق الـ TDD عليها، مع الانتباه أننا لا يجب أن نكتب أي لوجك داخل هذه الدالة قبل كتابة ال unit test الخاصة بها.

كما في الشكل التالي:

نقوم بكتابة وحدة الاختبار الخاصة بالـ increment 

النتيجة ستكون فشل (RED) وذلك بسبب أننا لم نكتب الـ logic الخاص بالـ increment بعد.

الآن نتجه إلى الكود الفعلي (الإنتاجي) ونقوم بكتابة اللوجك الخاص بالـ increment

بعد كتابة اللوجك الخاص بالـ increment نقوم بإعادة الاختبار:

نلاحظ نجاح الاختبار.

الخاتمة:

بعد العمل على تطوير البرمجيات لعدة سنوات، أصبح من الواضح أن TDD (Test-driven development) أصبحت أساسية لتطوير البرمجيات التي تسعى إلى أن تكون ذات جودة عالية وتقليل الأخطاء في الكود. فهي تساعد على زيادة فعالية العملية التطويرية وتحسين جودة المنتج النهائي.

وبالتالي، فإن استخدام الـ TDD يعد استثمارًا جيدًا لتحسين جودة وإنتاجية عملية التطوير.

المراجع:
0 تعليقات
Inline Feedbacks
View all comments

Recent Posts

  • All Post
  • Work Management
  • Technology Development
  • Software Development Practices
  • Flutter Development
  • Automation Testing Tools