يا جماعة الخير، السلام عليكم ورحمة الله.
بتذكر قبل كم سنة، كنا شغالين على نظام مالي ضخم ومعقد لشركة كبيرة. كان موعد الإطلاق النهائي على الأبواب، والضغط علينا وصل السما. الفريق كله، وأنا معهم، كنا زي اللي راكبين دوامة ما بتوقف. كل يوم الصبح، بنفتح قائمة الأخطاء (Bugs)، وبنقول “بسم الله” وبنبلش نصلح.
المشكلة ما كانت في تصليح الخطأ نفسه، لا. المشكلة كانت إنه كل ما نصلح خطأ في مكان، “بطق” خطأ ثاني في مكان ما إله أي علاقة! والله يا جماعة كنا بنلعب لعبة “اضرب الخلد” (Whac-A-Mole) اللعينة. بتعرفوها؟ هاي اللعبة اللي بتضل تضرب فيها الخلد بالمطرقة، وكل ما تضرب واحد، بيطلع لك واحد ثاني من حفرة ثانية. كان هذا هو حالنا بالضبط. أصلح مشكلة في الفواتير، تتعطل صفحة تقارير الأرباح. أضبط إشي في صلاحيات المستخدمين، فجأة نظام الدفع بصير يضرب إيرور. صرنا نخاف نلمس الكود. كل واحد فينا قبل ما يعمل `git push` كان ياخد نفس عميق ويقرأ المعوذات، لأنه مش عارف شو المصيبة الجديدة اللي رح تطلعله.
في يوم من الأيام، بعد ليلة طويلة من التصليحات اللي جابت تصليحات جديدة، اجتمعنا الصبح ووجوهنا ما بتتفسر. الإرهاق واليأس كان واضح علينا. وقتها قلت للفريق: “يا جماعة، إحنا بنحرث في البحر. شغلنا غلط. لازم نلاقي طريقة نضمن فيها إنه اللي بنصلحه ما يخرب إشي ثاني”. ومن هنا، بدأت رحلتنا الحقيقية مع ما يسمى بـ “اختبارات التراجع الآلية”، الأداة اللي أنقذتنا من هذا الجحيم.
ما هي لعبة “اضرب الخلد” في عالم البرمجة؟
قبل ما نغوص في الحل، خلوني أشرح أكتر عن هاي اللعبة المزعجة اللي كنا بنلعبها. في عالم تطوير البرمجيات، “اضرب الخلد” هو مصطلح بنستخدمه لوصف الوضع اللي بتكون فيه:
- تصلح خطأ (Bug): تجد حلاً لمشكلة معينة وتكتب الكود اللازم لها.
- يظهر خطأ جديد: بعد تطبيق الإصلاح، تكتشف أن ميزة أخرى في النظام، كانت تعمل بشكل ممتاز، قد تعطلت فجأة وبدون سبب واضح.
- تكرر العملية: تذهب لإصلاح الخطأ الجديد، ليتسبب إصلاحك في ظهور خطأ ثالث في مكان آخر… وهكذا دواليك.
هذه الظاهرة، اللي اسمها العلمي هو “التراجعات” أو “Regressions”، هي كابوس أي فريق تطوير. إنها تستنزف الوقت، تقتل المعنويات، وتجعل الثقة في جودة المنتج تقترب من الصفر. بتصير تخاف تعمل أي تغيير، حتى لو كان بسيطًا، لأنك مش ضامن تبعاته.
المنقذ الذي لم نكن نعلم أننا بحاجته: اختبارات التراجع (Regression Testing)
وسط هذه الفوضى، كان الحل يكمن في مفهوم بسيط لكنه قوي بشكل لا يصدق: اختبارات التراجع. الفكرة ببساطة هي أن يكون لديك شبكة أمان تمسك بأي خطأ غير متوقع قبل أن يصل للمستخدم.
ما هي اختبارات التراجع (Regression Tests)؟
ببساطة شديدة، اختبار التراجع هو عملية إعادة اختبار الأجزاء التي تم اختبارها سابقًا من البرنامج للتأكد من أن التغييرات الجديدة (سواء كانت إصلاح خطأ أو إضافة ميزة جديدة) لم تؤثر سلبًا على الوظائف الحالية. إنه سؤال بسيط نطرحه باستمرار: “هل ما زال كل شيء يعمل كما كان من قبل؟”.
فكر فيها كطبيب يفحص كل أعضاء جسمك الحيوية بعد أن يعطيك دواءً جديدًا لمرض معين. هو لا يكتفي بالتأكد من أن الدواء عالج المرض، بل يريد أن يتأكد من أنه لم يسبب أي أعراض جانبية ضارة في القلب أو الكلى أو أي مكان آخر.
لماذا هي مهمة لهذه الدرجة؟
- بناء الثقة: تمنحك أنت وفريقك الثقة للقيام بتغييرات وإعادة هيكلة (Refactoring) للكود دون خوف.
- توفير الوقت والمال: اكتشاف الخطأ في مرحلة التطوير أرخص بآلاف المرات من اكتشافه بعد إطلاق المنتج.
- تحسين الجودة: تضمن أن جودة المنتج لا تتدهور مع مرور الوقت وكثرة التعديلات.
- راحة البال: وهذا أهم إشي، بتخليك “تنام الليل مرتاح البال”، لأنك تعلم أن هناك حارسًا آليًا يراقب الكود باستمرار.
من اليدوي إلى الآلي: القفزة النوعية
في البداية، حاولنا تطبيق اختبارات التراجع بشكل يدوي. كان لدينا ملف Excel ضخم فيه مئات الحالات الاختبارية. مع كل تغيير بسيط، كان أحد أفراد فريق ضمان الجودة (QA) المسكين يقضي يومين أو ثلاثة وهو يمر على هذه القائمة نقطة نقطة. كانت عملية مملة، بطيئة، والأهم من ذلك، عرضة للخطأ البشري. والله إشي بجلط!
هنا يأتي سحر الأتمتة. اختبارات التراجع الآلية (Automated Regression Tests) هي كتابة كود برمجي يقوم باختبار الكود البرمجي الخاص بتطبيقك. هذه الاختبارات تعمل بشكل تلقائي وسريع جدًا، وتعطيك تغذية راجعة فورية.
كيف نبدأ؟ دليل عملي من “أبو عمر”
طيب يا أبو عمر، حمستنا. كيف نبدأ؟ الموضوع أبسط مما تتخيل. مش لازم تعمل كل إشي من أول يوم. حبة حبة يا جماعة.
الخطوة الأولى: تحديد الحالات الحرجة (Critical Paths)
لا تحاول أتمتة كل شيء في البداية. ابدأ بأهم مسارات المستخدم في تطبيقك. اسأل نفسك: “ما هي الوظائف التي إذا تعطلت، سيتوقف العمل تمامًا؟”.
نصيحة من خبرتي: في أي تطبيق، هناك 20% من الميزات يستخدمها 80% من المستخدمين. هذه هي نقطة البداية. ركز على:
- عملية تسجيل الدخول وإنشاء حساب جديد.
- الوظيفة الأساسية (مثلاً: إضافة منتج للسلة وإتمام الشراء في متجر إلكتروني).
- عمليات الدفع.
- أهم التقارير في لوحة التحكم.
الخطوة الثانية: اختيار الأدوات المناسبة
الأدوات تعتمد على التقنيات التي تستخدمها. هناك أدوات لكل شيء تقريبًا:
- لاختبارات الواجهة الأمامية (End-to-End): أدوات مثل Cypress, Playwright, أو Selenium. هذه الأدوات تحاكي المستخدم الحقيقي وهو يتصفح الموقع ويضغط على الأزرار ويملأ الحقول.
- لاختبارات الواجهة الخلفية (API & Unit Tests): أدوات مثل Jest أو Mocha في عالم JavaScript/Node.js، أو PyTest في عالم Python، أو JUnit في عالم Java.
الخطوة الثالثة: مثال عملي بسيط (باستخدام JavaScript و Jest)
لنفترض أن لدينا دالة (function) بسيطة في متجرنا الإلكتروني تحسب المجموع النهائي لسلة المشتريات.
// original function: cart-utils.js
function calculateTotalPrice(items) {
// items is an array of objects like { price: 10, quantity: 2 }
return items.reduce((total, item) => total + (item.price * item.quantity), 0);
}
الآن، سنكتب اختبار تراجع بسيط باستخدام Jest للتأكد من أنها تعمل بشكل صحيح.
// test file: cart-utils.test.js
test('should calculate the total price of items correctly', () => {
const items = [
{ price: 10, quantity: 2 }, // 20
{ price: 5, quantity: 1 }, // 5
{ price: 2.5, quantity: 4 } // 10
];
expect(calculateTotalPrice(items)).toBe(35);
});
هذا الاختبار هو “شبكة الأمان” الخاصة بنا. الآن، لنفترض أن مبرمجًا جديدًا انضم للفريق، وطُلب منه إضافة ميزة تطبيق خصم بنسبة 10% على كل منتج. فقام بتعديل الدالة الأصلية كالتالي:
// Modified (and broken) function
function calculateTotalPrice(items) {
// Developer adds a discount feature, but makes a mistake
return items.reduce((total, item) => {
const itemPriceWithDiscount = item.price * 0.90; // Applying 10% discount
return total + (itemPriceWithDiscount * item.quantity);
}, 0);
}
للوهلة الأولى، قد يبدو الكود صحيحًا. لكن المبرمج طبق الخصم على كل شيء، حتى لو لم يكن من المفترض أن يطبق! هنا يأتي دور اختبار التراجع. عندما نقوم بتشغيل الاختبار القديم الذي لم نلمسه، سيفشل فورًا:
FAIL ./cart-utils.test.js
● should calculate the total price of items correctly
expect(received).toBe(expected) // toBe uses Object.is
Expected: 35
Received: 31.5
بوم! لقد أمسكنا بالخلد قبل أن يخرج من حفرته. الاختبار أخبرنا فورًا أن التغيير الجديد قد “كسر” الوظيفة الأساسية. الآن يمكن للمبرمج أن يرى الخطأ ويصلحه (مثلاً، عن طريق تمرير متغير إضافي للدالة لتحديد متى يتم تطبيق الخصم) قبل أن يصل الكود إلى مرحلة الإنتاج.
الخطوة الرابعة: دمج الاختبارات في سير العمل (CI/CD)
القوة الحقيقية تظهر عندما تجعل هذه الاختبارات تعمل تلقائيًا مع كل تغيير. باستخدام أدوات مثل GitHub Actions, GitLab CI, أو Jenkins، يمكنك إعداد نظام بحيث:
- عندما يقوم أي مبرمج برفع كود جديد (push).
- يقوم السيرفر تلقائيًا بسحب الكود.
- ويقوم بتشغيل جميع اختبارات التراجع.
- إذا فشل أي اختبار، يتم رفض التغيير وإرسال تنبيه فوري للمبرمج.
هذا يضمن أن الكود الأساسي في المشروع (main branch) دائمًا نظيف وسليم ويعمل 100%.
نصائح من قلب الميدان
- ابدأ صغيراً وتدريجياً: لا تحاول أتمتة كل شيء مرة واحدة. ابدأ باختبار واحد لوظيفة حرجة. ثم أضف المزيد مع الوقت.
- اجعل اختباراتك سريعة وموثوقة: الاختبارات البطيئة أو التي تفشل عشوائيًا (Flaky Tests) أسوأ من عدم وجود اختبارات، لأن الفريق سيفقد الثقة بها ويتجاهلها.
- كل خطأ جديد هو فرصة لاختبار جديد: عندما تجد خطأ في الإنتاج، لا تكتفِ بإصلاحه. أولاً، اكتب اختبار تراجع يفشل بسبب هذا الخطأ. ثانيًا، أصلح الخطأ. ثالثًا، تأكد من أن الاختبار أصبح ينجح. بهذه الطريقة، تضمن أن هذا الخطأ بالذات لن يعود أبدًا.
- اختبر السلوك، وليس تفاصيل التنفيذ: يجب أن يهتم اختبارك بـ “ماذا” تفعله الدالة، وليس “كيف” تفعله. هذا يجعل اختباراتك أكثر مرونة عند إعادة هيكلة الكود.
الخلاصة: من لعبة “اضرب الخلد” إلى بناء واثق 🏗️
في النهاية، التحول إلى اختبارات التراجع الآلية لم يكن مجرد تحسين تقني، بل كان تحولاً في ثقافة الفريق بأكمله. انتقلنا من الخوف والتوتر مع كل إصدار جديد، إلى الثقة والسرعة في التطوير. لم نعد نلعب لعبة “اضرب الخلد”، بل أصبحنا نبني برجًا قويًا، طوبة فوق طوبة، ونحن نعلم أن الأساس متين بفضل شبكة الأمان التي بنيناها.
نصيحتي لكل مبرمج ومدير فريق: لا تعتبروا الاختبارات الآلية رفاهية أو شيئًا مؤجلاً “لبعدين”. إنها استثمار أساسي في جودة منتجكم، وفي صحة فريقكم النفسية، وفي قدرتكم على النمو والتطور بسرعة وأمان.
استثمروا في جودة الكود تبعكم، لأنه هو الأساس اللي بتبنوا عليه كل نجاحكم. والله يوفقكم يا جماعة الخير! 💪