14

كيف تقوم بإختبار شفرتك

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

في حالة كنت ممن يخضعون شفرته للإختبار فهل لك أن تخبرنا عن الأدوات والطرق المختلفة التي تستخدمها؟

يرجى الدخول لحسابك أو تسجيل حساب لتستطيع إضافة تعليق
حساب جديد دخول

التعليقات

12

أهم مشاريعي و المشروع الوحيد الذي قمتُ بعمل اختبارات موسعة له هو عبارة عن مُفسِّر interpreter، و الاختبارات التي أجريها عليه بشكل دوري -بعد كل تغيير في الأكواد- تقوم علي أساس التأكد من قدرته علي قراءة ملفات لغة البرمجة التي يخدمها، و تنفيذ الأوامر المكتوبة في تلك الملفات بشكل صحيح، و اكتشاف الأخطاء التي توجد في بعض الملفات، و لتحقيق ذلك قمتُ بعمل مكتبة تضم مئات الملفات التي تختبر كل جزئية من جزئيات اللغة، و كذلك قمتُ بكتابة بعض الأخطاء المتعمدة في بعض تلك الملفات لأري هل سيقوم المفسر باكتشافها أم لا.

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

كل تلك الاختبارات يمكن القيام بها ببساطة من خلال سطر الأوامر في الـwindows و الـGNU\linux، و لكن بما أننى أقوم في بعض الأحيان باختبار ملف واحد فقط، و في بعض الأحيان الأخرى أقوم باختبار كل الملفات التي في مجلد الاختبار دفعة واحدة، و في أحيان أخري أقوم باختبار مجموعة معينة من الملفات (مثلاً الملفات التي تختبر القدرة علي التعامل السليم مع الوراثة المتعددة multiple inheritance)، فبسبب ذلك قمتُ بعمل أداة بسيطة ذات واجهة رسومية تجعل الأمر في غاية الاختصار من حيث الوقت و الجهد المبذولين في عملية الاختبار، و يمكنني بنقرات بسيطة من الفأرة أن أنجز الاختبارات التي أريد بمنتهي السرعة و السلاسة.

كل تلك الأمور استهلكت الكثير من الوقت و الجهد في بنائها و اختبارها، و لكنها وفرت عليَّ وقتاً و جهداً هائلين، و أعطتني القدرة علي أن أعمل براحتي في المفسر و أغير في أكواده بحرية كبيرة للغاية، لأنني صرتُ قادراً علي اكتشاف أي مشكلة تحدث و تفسد أي وظيفة كانت تعمل بشكل صحيح في الإصدارة القديمة من المفسر (مهما كانت تلك الوظيفة صغيرة و دقيقة)، و بالاستعانة بخدمات الـNetBeans و git يمكنني دائماً معرفة أي التغييرات التي أجريتُها حديثاً أدي إلي إفساد الأمور، و هكذا أقضي الوقت في العمل علي الأمور المهمة بدلاً من إضاعة الوقت و الجهد علي أمور جانبية الهدف الوحيد من ورائها هو خدمة الأمور الهامة لا أكثر.

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

  • أولا أضع أمامي الهدف النهائي المطلوب من الكود متجاهلاً كل الاعتبارات الأخرى

  • بعد أن أصل إلى المطلوب وأعلم أنه أصبح بالإمكان الوصول للنتيجة كما نريد

  • حينها أبدأ باكتشاف عقد المنشار وعنق الزجاجة وذلك من خلال أدوات وطرق أن أبنيها بحيث أعرف أين يتم هدر الوقت

  • حينها أبدأ بإعداة صياغة الكود لاختزال تلك الاستدعاءات المتكررة التي تستنزف الوقت

  • مع التجريب مع كل خطوة لأتأكد أن الكود مازال يعطي نفس النتيجة التي توصلت إليها.

  • وفي حال سأقوم بتغيير جذري أقوم بأخذ نسخة احتياطية تحسبا لأي تشويه للكود أو في حال انحراف النتيجة عن ما هو مطلوب

هل تقصد أنك بنيت أدوات الإختبارات بنفسك أم أنك تستخدم أدوات معروفة؟

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

منها القياس ومنها فحص الصلاحيات و منها إعادة التوجيه

أقصد لم أستخدم الأدوات الجاهزة مثل Unit Test بشكل واسع وإنما في نطاقات ضيقة جداً

أما على مستوى التنفيذ النهائي فأستخدم أدواتي و أزرع نقاط لكشف الأخطاء أثناء حدوثها لكي أعرف أين حدث الخطأ بالضبط حتى لا أضطر لحشر try catch في كل مكان

وإنما أستعضت عنه بلاقط الاستثناءات العام باستخدام PostSharp حيث يقوم بالتقاط أي أستثناء في أي مكان دون الحاجة لزرع try catch أبداً

أغلب اختباراتي تكمن في تجربة كمستخدم مخرب أو بمعنى آخر أستخدم الأداة بشكل غير عادي مثل العبث في المدخلات و المخرجات...

طبعا الأمر ليس عشوائي بل يكون حسب قطعة الكود...

بلنسبة لكود الجافا استخدم Junit

بلنسبة لتطبيقات الاندرويد استخدم Monkey الذي يقوم بعمل اختبارات عشوائية للتطبيق