نجح مسار CI/CD الخاص بي لمدة 3 أشهر — ثم قرأت السجلات

علامات الصح الخضراء تمنح شعوراً جيداً. كل طلب سحب (pull request) قد نجح. كل عملية نشر (deploy) تمت بنجاح.

ثم أبلغ أحد المستخدمين عن ميزة معطلة. كانت معطلة منذ أسابيع.

فتحت سجلات الـ pipeline. كانت عمليات البناء (builds) الناجحة تخدعنا.

بدت عمليتنا مثالية:

  • Linting
  • اختبارات الوحدة (Unit tests)
  • اختبارات التكامل (Integration tests)
  • البناء (Build)
  • النشر (Deploy)

كانت كل خطوة تحقق نسبة نجاح 100% لعدة أشهر.

زر التصدير لم يفعل شيئاً عند النقر عليه. لم يظهر أي خطأ. تتبعت الأمر حتى وصلت إلى تغيير تم منذ 11 أسبوعاً. نجح الـ pipeline. تمت الموافقة على مراجعة الكود (code review). كانت الميزة معطلة منذ البداية.

لم تكن المشكلة في الكود الخاص بنا، بل في كود الاختبار.

كانت اختبارات التكامل لدينا تستخدم الـ mocks لكل شيء. قمنا بعمل mock لخدمة التصدير بالكامل. قام الاختبار بفحص الـ mock بدلاً من الكود الحقيقي. كان الـ mock يعيد دائماً حالة نجاح.

وقعنا في فخ الإفراط في استخدام الـ mocks:

  • اختبارات الوحدة (Unit tests): قمنا بعمل mock لكل شيء لعزل الوحدة. هذا أمر جيد.
  • اختبارات التكامل (Integration tests): قمنا بعمل mock لكل شيء من أجل السرعة. هذا خطأ.
  • اختبارات E2E: أغفلنا هذا المسار تحديداً.

كانت اختبارات التكامل لدينا مجرد اختبارات وحدة مكلفة. كانت تتحقق من أن الـ mocks تعمل، ولم تتحقق من أن الكود الخاص بنا يعمل.

أجريت ثلاثة تغييرات لإصلاح ذلك:

  1. قصر استخدام الـ mocks على اختبارات الوحدة فقط. يجب أن تتصل اختبارات التكامل بقواعد بيانات، وAPIs، وأنظمة ملفات حقيقية. إذا كان الاختبار بطيئاً، فلا تخفِ ذلك باستخدام mock، بل استخدم تلك السرعة كإشارة للتحسين (optimize).

  2. إضافة اختبارات التعاقد (contract tests). تضمن هذه الاختبارات تطابق الـ mocks مع سلوك الخدمة الحقيقي. إذا أعاد الـ mock بيانات لا يمكن للخدمة الحقيقية إعادتها، سيفشل اختبار التعاقد.

  3. تتبع التغطية الحقيقية (real coverage). توقفنا عن النظر إلى معدلات النجاح البسيطة، وبدأنا ننظر إلى ما تختبره الاختبارات فعلياً. انخفضت أرقام التغطية لدينا من 94% إلى 67%. كان هذا هو المقياس الأكثر صدقاً لدينا.

الـ pipeline الأخضر لا يعني أن الكود الخاص بك يعمل، بل يعني أن اختباراتك قد نجحت. هذان أمران مختلفان.

أخطر الأخطاء (bugs) هي تلك التي يخبرك الـ pipeline بأنها سليمة.

اسأل نفسك هذه الأسئلة:

  • هل تكتشف اختباراتي الأخطاء أم أنها مجرد تأكيد لعمل الـ mocks؟
  • هل تقوم اختبارات التكامل الخاصة بي بعملية تكامل حقيقية؟
  • إذا قمت بإزالة جميع الـ mocks، فكم عدد الاختبارات التي ستظل ناجحة؟
  • هل أقيس التغطية (coverage) أم الثقة (confidence)؟

الـ pipeline الذي لا يفشل أبداً ليس موثوقاً، بل هو غير مختبر.

المصدر: https://dev.to/kollittle/my-cicd-pipeline-passed-for-3-months-then-i-read-the-logs-4mbj