الانحدار هو خطأ يظهر بعد إجراء تغييرات في الكود، على الرغم من أن نفس الوظيفة كانت تعمل بشكل صحيح من قبل. يعني الانحدار أن التغيير الجديد «كسر» ما تم كتابته واختباره سابقاً. إنها واحدة من أكثر المشاكل شيوعاً وخطورة في التطوير: عند إصلاح خطأ واحد، قد يكسر المطور ثلاث وظائف أخرى دون قصد. وفقاً لـ Capers Jones Software Engineering 2023، متوسط كثافة أخطاء الانحدار هو 1–3 لكل 100 سطر من الكود تم تغييرها. دعنا نستعرض أسباب الانحدار وطرق اكتشافه واستراتيجيات الوقاية.
النقاط الرئيسية
الانحدار هو حالة تتوقف فيها وظيفة كانت تعمل في إصدار سابق عن العمل بعد إجراء تغييرات. يمكن أن يكون التغيير أي شيء: إصلاح خطأ، إضافة ميزة جديدة، إعادة هيكلة، تحديث مكتبة أو حتى تغيير تكوين. الانحدار هو العدو الرئيسي للاستقرار: كل تغيير يخاطر بكسر شيء تم التحقق منه وإصداره بالفعل.
المصطلح يأتي من الاختبار: اختبار الانحدار هو إعادة تنفيذ الاختبارات الموجودة بعد كل تغيير. إذا فشل اختبار كان ناجحاً سابقاً، فقد حدث انحدار. بمعنى أوسع، الانحدار ليس فقط فشل اختبار، بل أي تدهور في السلوك يلاحظه المستخدم أو فريق ضمان الجودة. وفقاً لـ Tricentis State of Testing 2023، تمثل الانحدارات 35–45% من جميع الأخطاء الموجودة في الإنتاج.
ما يميز الانحدار عن الخطأ العادي هو السياق الزمني: الخطأ العادي ربما كان موجوداً دائماً، بينما الانحدار دائماً نتيجة تغيير. هذا تمييز مهم لأن العثور على سبب الانحدار يبدأ بتحليل ما تغير بين «كان يعمل» و«توقف عن العمل». Git bisect هي الأداة القياسية للعثور على التعديل الذي تسبب في الانحدار.
الانحدار المحلي — تغيير في الوحدة A يكسر وظيفة في نفس الوحدة A. مثال: يعيد المطور كتابة دالة فرز فتتوقف عن معالجة مصفوفة فارغة بشكل صحيح. الانحدار المحلي هو الأسهل في الاكتشاف والإصلاح لأن السبب والنتيجة قريبان.
الانحدار البعيد — تغيير في الوحدة A يكسر وظيفة في الوحدة B، غير متصلة مباشرة بالكود ولكنها متصلة بالبيانات أو التوقيت. مثال: تغيير مخطط قاعدة البيانات في وحدة «المستخدمون» يكسر تقريراً في وحدة «التحليلات» التي تستخدم نفس الجدول. الانحدارات البعيدة هي الأكثر غدراً: المطور لا يشك في أن تغييره سيؤثر على وحدة أخرى.
انحدار الآثار الجانبية — تغيير في تأثير جانبي (تسجيل، تخزين مؤقت، إرسال إشعارات) يكسر السلوك المتوقع. مثال: يضيف المطور تخزيناً مؤقتاً لتسريع الأداء، ولكن بسبب التخزين المؤقت القديم، يرى المستخدمون بيانات قديمة. يصعب اكتشاف انحدارات الآثار الجانبية بالاختبارات الآلية لأن الآثار الجانبية غالباً غير مغطاة بالاختبارات.
انحدار الأداء — يستمر الكود في العمل بشكل صحيح وظيفياً ولكنه أبطأ من ذي قبل. مثال: خوارزمية تشفير جديدة تنتج نفس النتائج، لكن وقت التنفيذ زاد من 2 مللي ثانية إلى 200 مللي ثانية. لا يتم اكتشاف انحدارات الأداء بواسطة اختبارات الوحدة العادية — بل هناك حاجة إلى المقاييس المعيارية والتنميط.
| نوع الانحدار | مثال | طريقة الاكتشاف |
|---|---|---|
| محلي | فرز معطل | اختبارات الوحدة |
| بعيد | تغيير مخطط قاعدة البيانات | اختبارات التكامل |
| آثار جانبية | تخزين مؤقت قديم | اختبارات E2E |
| أداء | استجابة أبطأ | مقاييس معيارية |
السبب الأول هو اقتران الكود. كلما زاد اعتماد الوحدات على بعضها البعض، زاد احتمال أن يتسبب تغيير في واحدة في انحدار في أخرى. الأنماط المضادة الكلاسيكية: الكائن العملاق (كائن يفعل كل شيء)، جراحة البندقية (تغيير في مكان واحد يتطلب تعديلات في عشرات الأماكن)، التبعية الدائرية. تقليل الاقتران هو مسألة معمارية: مبادئ SOLID، حقن التبعية، المعمارية السداسية.
السبب الثاني هو نقص الاختبارات للوظيفة المعدلة. إذا لم يكن الكود مغطى بالاختبارات، فإن المطور لا يعلم بوجود انحدار إلا من فريق ضمان الجودة أو المستخدمين. وفقاً لمدونة Google للاختبارات، المشاريع التي تغطي اختباراتها >75% من الكود لديها انحدارات أقل بـ5 مرات من المشاريع التي تغطي <25%. يضمن التطوير الموجه بالاختبارات (TDD) كتابة الاختبارات قبل الكود، وليس «عندما يتوفر الوقت».
السبب الثالث هو العامل البشري. المطور لا يعرف بوجود وظائف ذات صلة، لا يفهم جميع التبعيات أو هو ببساطة في عجلة من أمره. السبب هو عدم مشاركة المعرفة بقاعدة الكود بشكل كافٍ. الحلول: مراجعة الكود مع مطورين من وحدات أخرى، البرمجة الثنائية، توثيق المعمارية. عامل الحافلة للمشروع يتناسب عكسياً مع عدد القرارات المعمارية الموثقة.
اختبار الانحدار هو عملية إعادة تنفيذ الاختبارات الموجودة بعد كل تغيير للتحقق من أن الوظائف القديمة لم تُكسر. إنها الطريقة الوحيدة لضمان أن التغيير الجديد لم يخل بالكود الموجود. بدون اختبار الانحدار، كل إصدار هو يانصيب: المطور يأمل ألا يكون قد كسر شيئاً لكنه لا يستطيع التأكيد.
اختبار الانحدار اليدوي هو النهج الأكثر تكلفة والأقل فعالية. مع نمو المشروع، يزداد عدد سيناريوهات اختبار الانحدار خطياً، بينما يزداد وقت التنفيذ اليدوي بشكل أسي. بعد 2–3 سنوات من التطوير، قد يستغرق اختبار الانحدار اليدوي 2–3 أسابيع، مما يجعل الإصدارات المتكررة مستحيلة. الحل الوحيد هو الأتمتة.
ينقسم اختبار الانحدار الآلي إلى مستويات وفقاً لهرم الاختبارات:
وفقاً لمدونة Google للاختبارات، النسبة المثلى هي 70% اختبارات وحدة، 20% اختبارات تكامل، 10% E2E. الانحراف عن هذه النسبة يقلل من فعالية اختبار الانحدار: كثرة اختبارات E2E تبطئ خط الأنابيب، قلة اختبارات الوحدة تترك الأخطاء الدقيقة دون اكتشاف.
الاستراتيجية الأولى هي الانحدار الكامل. يتم تشغيل جميع اختبارات المشروع. النهج الأكثر موثوقية ولكنه الأبطأ. مناسب للمشاريع الصغيرة (حتى 10,000 اختبار، وقت التشغيل <30 دقيقة). للمشاريع الكبيرة، قد يستغرق الانحدار الكامل ساعات، مما يجعل خط أنابيب CI/CD غير عملي.
الاستراتيجية الثانية هي الانحدار الانتقائي. يتم تشغيل الاختبارات المتعلقة فقط بالكود المعدل. يُستخدم رسم بياني لتبعيات الكود لتحديد العلاقات. الأدوات: Bazel (Google)، Nx (JavaScript)، sbt (Scala). يوفر الانحدار الانتقائي 60–80% من وقت التشغيل ولكنه يتطلب بناءً دقيقاً لرسم التبعيات — الأخطاء تؤدي إلى انحدارات غير مكتشفة.
الاستراتيجية الثالثة هي الانحدار حسب الأولوية. يتم ترتيب جميع الاختبارات حسب الأولوية: المسار الحرج (أهم سيناريوهات المستخدم)، المخاطر العالية (الكود بتاريخ من الأخطاء)، الكود المعدل (الكود المتأثر بالتغيير). يتم تشغيل الاختبارات الأعلى أولوية أولاً — إذا نجحت، يتلقى المطور ردود فعل سريعة. تشغيل محدود الوقت: يتم فحص الاختبارات الحرجة في 10 دقائق، والباقي يعمل في الخلفية.
الخطوة الأولى والأكثر أهمية هي ثقافة كتابة الاختبارات. يجب أن يكون كل تغيير مصحوباً باختبار يتحقق من أن التغيير يعمل واختبار يتحقق من أن شيئاً لم يُكسر. يعطي التطوير الموجه بالاختبارات (TDD) أفضل النتائج: يكتب المطور أولاً اختباراً فاشلاً، ثم الكود الذي ينجح فيه. هذا يضمن وجود الاختبار قبل الكود.
الخطوة الثانية هي خط أنابيب CI/CD مع تنفيذ إلزامي للاختبارات. لا يمكن دمج طلب السحب حتى تجتاز جميع الاختبارات. لا يمكن «تخطي» الاختبارات بسبب الاستعجال — التغييرات العاجلة تمر عبر مجموعة اختبارات متسارعة ولكنها إلزامية. وفقاً لـ Google DevOps Research، الفرق التي لديها CI/CD إلزامي لديها انحدارات أقل بـ3 مرات في الإنتاج.
الخطوة الثالثة هي المراقبة في الإنتاج. حتى أفضل الاختبارات لا تضمن حماية 100% ضد الانحدار. أدوات المراقبة (Sentry، Datadog، New Relic) يجب أن تتابع المقاييس الرئيسية بعد كل نشر: معدل الخطأ، زمن الاستجابة، الإنتاجية. الاسترجاع التلقائي عند تجاوز الحدود هو شبكة أمان إذا وصل الانحدار إلى الإنتاج.
الخطوة الرابعة هي مراجعة الكود بعقلية الانحدار. يجب على المراجع أن يسأل: «ما الوحدات الأخرى التي قد تتعطل بسبب هذا التغيير؟». لا يكفي التحقق من صحة الكود — بل يجب التحقق من أنه لن يخل بالوظائف ذات الصلة. يجب أن تتضمن قائمة التحقق لمراجعة الكود بند «التحقق من الانحدار في الوحدات ذات الصلة».
الأسئلة الشائعة
الانحدار هو خطأ لم يكن موجوداً من قبل. الخطأ العادي ربما كان موجوداً منذ إنشاء الميزة. الانحدار دائماً مرتبط بتغيير محدد — وهذا يسمح باستخدام git bisect للعثور على السبب.
استخدم git bisect: حدد التعديل حيث كان كل شيء يعمل والتعديل حيث تعطل. يقوم Git بإجراء بحث ثنائي في التاريخ ويجد التعديل الذي تسبب في الانحدار. هذا يعمل حتى للمشاريع الكبيرة التي تحتوي على آلاف التعديلات.
لا يوجد رقم محدد، لكن هناك قاعدة تجريبية: تغطية تدفقات المستخدم الرئيسية يجب أن تكون 100%، وتغطية جميع الوظائف لا تقل عن 70%. الجودة أهم من الكمية: اختبار يتحقق من حالة حافة يساوي أكثر من عشرة اختبارات على المسار الطبيعي.
نعم، وهذا يسمى انحدار البنية التحتية. تحديث نظام التشغيل، تغيير إصدار قاعدة البيانات، تحديث شهادة SSL أو تغيير تكوين خادم الويب يمكن أن يكسر كوداً كان يعمل. تساعد البنية التحتية ككود (IaC) واختبار البنية التحتية (Test Kitchen، Terratest) في اكتشاف مثل هذه الانحدارات.
ابدأ بتدفق مستخدم حرج واحد. اكتب اختباراً آلياً لأهم سيناريو (تسجيل الدخول، إتمام الطلب). وضح في عرض توضيحي كيف يكتشف الاختبار انحداراً. بمجرد أن يرى الفريق الفائدة، قم بتوسيع التغطية تدريجياً.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.