التعلّم من حوادث الإنتاج
التعلّم من حوادث الإنتاج حلقةُ تغذية راجعة تحوّل إخفاقاً رآه المستخدمون الحقيقيون إلى تحسين دائم. والحادثة (Incident) حدث غير مخطط له في بيئة الإنتاج يضرّ بالمستخدمين أو بالعمل: انقطاع للخدمة، أو بيانات خاطئة، أو مبلغ يُخصم مرتين. وبعد استعادة الخدمة يراجع الفريق الحادثة في مراجعة ما بعد الحادثة (Postmortem)، ويحدد الاختبارات أو الفحوص التي كان يجب أن تكشف المشكلة، ثم يضيفها، وغالباً على هيئة اختبارات انحدار (Regression Tests).
مثال: خُصم المبلغ من بعض العملاء مرتين بعد إصدار جديد. الإصلاح يوقف الخصم المكرر، أما التعلّم فهو أن تسأل لماذا لم يُشغَّل أي اختبار أمام مزوّد دفع بطيء، ثم تضيف اختباراً يفعل ذلك.
لماذا يهم
حادثة الإنتاج أغلى طريقة لاكتشاف عيب: يتضرر المستخدمون، ويصرف فريقا الدعم والمالية وقتاً في معالجتها، ويعمل الفريق تحت الضغط. وإذا كانت النتيجة الوحيدة إصلاحاً عاجلاً (Hotfix)، تبقى الظروف التي سمحت للعيب بالتسرّب كما هي، فتتبعها حادثة مشابهة.
وبالنسبة إلى المختبِر، كل حادثة دليلٌ عن نهج الاختبار لا تقدّمه أي مراجعة: فهي تُظهر بالضبط أين لم يطابق الواقعَ أساسُ الاختبار (Test Basis) أو مستوياتُه أو بيئاتُه أو مراجعُ الاختبار (Test Oracles). واستخدام هذا الدليل دون لوم يُبقي حزمة الانحدار مرتبطة بمخاطر حقيقية لا بالتخمين.
من الحادثة إلى الوقاية: حلقة التغذية الراجعة
يبدأ هذا الدرس من حيث ينتهي الرصد. والترتيب مهم: استعد الخدمة أولاً، ثم ابحث في الأسباب، ثم غيّر الاختبارات والعملية أخيراً بعد أن تتضح الحقائق.
بمصطلحات ISTQB، ما يواجهه المستخدمون في الحادثة إخفاقٌ (Failure): النظام لا يؤدي ما هو مطلوب منه. وقد يكون سببه عيباً في الشيفرة، لكنه قد يكون أيضاً الإعدادات أو البيانات أو السعة أو خدمة طرف ثالث؛ لذلك تحدد المراجعة ماذا أخفق ولماذا قبل أن تقرر أن الحل إصلاحٌ واختبار جديد.
- الرصد والإعلان: تنبيه أو فحص اصطناعي (Synthetic Check) أو بلاغ من عميل يفتح سجلَّ حادثة فيه الوقت والأثر ومالكٌ مسؤول.
- التخفيف (Mitigation): أوقف الضرر بالتراجع عن الإصدار (Rollback) أو بمفتاح ميزة (Feature Flag) أو بتغيير في الإعدادات. والتخفيف ليس الإصلاح، بل يمنحك وقتاً لإيجاده.
- إعادة بناء الجدول الزمني: عمليات النشر وتغييرات الإعدادات والتنبيهات والسجلات والقرارات، كلها بمنطقة زمنية واحدة.
- عقد مراجعة ما بعد الحادثة دون لوم: الأثر، والجدول الزمني، والأسباب المساهمة، وبنود العمل.
- تحليل فجوة الاختبار: أي اختبار أو فحص أو مراجعة كان يمكن أن يكشف المشكلة، وعلى أي مستوى، ولماذا لم يكشفها.
- الوقاية والتحقق: أضف اختبارات الانحدار والإجراءات الأخرى، لكلٍّ منها مالك وموعد، وتأكد من إنجازها.
- 1الرصد والإعلانالوقت والأثر والمالكتنبيه أو فحص اصطناعي أو بلاغ من عميل يفتح سجل الحادثة
- 2التخفيفليس الإصلاح بعدالتراجع عن الإصدار أو مفتاح ميزة أو تغيير في الإعدادات يوقف الضررالخدمة أولاً
- 3إعادة بناء الجدول الزمنيالنشر وتغييرات الإعدادات والتنبيهات والسجلات والقرارات، بمنطقة زمنية واحدة
- 4مراجعة ما بعد الحادثة دون لومالأثر والجدول الزمني والأسباب وبنود العملالأسباب المساهمة في النظام والعملية، لا شخص يُعاقَب
- 5تحليل فجوة الاختبارأي اختبار أو فحص كان يمكن أن يكشفها، وعلى أي مستوى، ولماذا لم يكشفهايقوده المختبِر
- 6اختبارات الانحدار والإجراءات الأخرىاختبارات ومتطلب وبيئة ومراقبة، لكلٍّ منها مالك وموعد
- 7التحققيفشل الاختبار الجديد على النسخة المعيبة وينجح مع الإصلاح، وتُغلق كل البنود
طوال الخطوات 3–5 دون لوم: اسأل ماذا ولماذا، لا مَن
بعد ذلك:إلى حزمة الانحدار وتحليل المخاطر للإصدار التالي
مراجعات ما بعد الحادثة دون لوم
قدّم درس ثقافة الجودة مراجعةَ ما بعد الحادثة بوصفها سجلاً مكتوباً للحادثة: أثرها ورصدها وتخفيفها وأسبابها والإجراءات اللاحقة. وهنا ستعقد واحدة بنفسك. ويوصي كتاب Google عن هندسة موثوقية المواقع (SRE) بالاتفاق على دواعي عقدها مسبقاً، مثل: انقطاع أو تدهور يراه المستخدمون ويتجاوز حداً معيناً، أو فقدان أي بيانات، أو تدخل يدوي كالتراجع عن إصدار، أو وقت حلّ طويل، أو إخفاق لم تكشفه المراقبة.
ومعنى «دون لوم» (Blameless) أن المراجعة تبحث عن الأسباب المساهمة في النظام والعملية، لا عن شخص تعاقبه، وتفترض أن الجميع تصرّفوا بحسن نية وفق المعلومات التي كانت لديهم. وهذا أمر عملي لا مجاملة: فمن يخشى اللوم يُغفل التفاصيل، فتفوت المراجعةَ الأسبابُ الحقيقية. ولا يعني ذلك غياب المساءلة، فلكل بند عمل مالكٌ مسمّى.
- صيغة لائمة: «نسي المطور حالة انتهاء المهلة». صيغة دون لوم: «لم يكن لمسار إعادة المحاولة اختبار، ولا تتضمن قائمة مراجعة الشيفرة شيئاً عن الاستجابات البطيئة».
- صيغة لائمة: «فات فريقَ الجودة اكتشافُه». صيغة دون لوم: «محاكي الدفع في بيئة الاختبار يجيب دائماً في أقل من ثانية، فلم يُنفَّذ مسار انتهاء المهلة قط».
- «الخطأ البشري» ليس سبباً جذرياً بمفرده أبداً: اسأل ما الذي جعل الخطأ سهل الوقوع وصعب الملاحظة.
من مراجعة الحادثة إلى فجوات الاختبار واختبارات الانحدار
إسهام المختبِر الأساسي في مراجعة ما بعد الحادثة هو تحليل فجوة الاختبار. تتبّع الإخفاق رجوعاً عبر عملية الاختبار: هل كان لهذا السلوك متطلب وشرط اختبار وحالة اختبار؟ وهل شُغّل الاختبار على هذا الإصدار في بيئة تشبه الإنتاج؟ كل «لا» تدل على فجوة، وكثيراً ما تكون للحادثة الواحدة عدة فجوات. ولكل نوع من الفجوات إجراء مختلف.
- شرط اختبار أو حالة اختبار غائبة: لم يذكر المتطلب ولا تحليل المخاطر هذا الموقف، أو لم يصل إليه تصميم الاختبار، كغياب القيم الحدّية عند الحافة. أضف الشرط أو معيار القبول أو حالة الاختبار.
- مستوى اختبار خاطئ: كان هناك اختبار، لكنه شامل من البداية إلى النهاية (End-to-End) على المسار السعيد (Happy Path) وحده، واختبار الوحدة أو اختبار API يصل إلى الفرع المعيب بسهولة أكبر.
- بيانات أو بيئة غير واقعية: بيانات الاختبار أو المحاكيات أو المنطقة الزمنية أو الإعدادات أو الأحجام تختلف عن الإنتاج.
- مرجع اختبار ضعيف: نُفّذ الاختبار لكنه لم يتحقق من النتيجة التي أخطأت، كأن يفحص رمز حالة HTTP دون عدد مرات الخصم.
- اختبار لم يُشغَّل: تُخطّي، أو عُزل لأنه متذبذب (Flaky)، أو لم يدخل ضمن اختيار اختبارات الانحدار لهذا التغيير.
- فجوة رصد: اكتشف المستخدمون المشكلة قبل المراقبة. وهذا الإجراء يخص المراقبة لا حزمة الاختبارات.
جرّبها: مولّد سيناريوهات الانحدار جرّبها: مولّد حالات الاختبار
مثال تطبيقي: خصم مزدوج بعد إصدار
حادثة افتراضية في متجر إلكتروني: خفّض الإصدار 7.3 مهلة وحدة الدفع (Payment Client) من 30 ثانية إلى 10 ثوانٍ. وتحت الحِمل كان المزوّد يجيب أحياناً بعد أكثر من 10 ثوانٍ، فتعيد وحدة الدفع المحاولة بمرجع دفع جديد يعامله المزوّد دفعةً جديدة، فخُصم من بعض العملاء مرتين.
يلخّص المقتطف أدناه المراجعة (التوقيت UTC+3): نُشر الإصدار الساعة 09:40، ووقع أول خصم مزدوج 09:58 (اكتُشف لاحقاً في سجلات الدفع)، ووصلت أول شكوى إلى الدعم 11:05، وأُعلنت الحادثة 11:30، وخُفّفت 11:50 بإعادة المهلة إلى 30 ثانية عبر الإعدادات، واستُردّت المبالغ المكررة لـ37 طلباً بحلول 15:00. لاحظ أن العملاء، لا المراقبة، هم من رصدوا المشكلة بعد 67 دقيقة من أول خصم مزدوج، وأن معظم بنود العمل اختبارات وفحوص لا إصلاحٌ للشيفرة.
الأسباب المساهمة، دون تسمية أفراد: إعادة المحاولة ترسل مرجع دفع جديداً فلا يتعرّف المزوّد عليها؛ ومتطلب الدفع لم يذكر إعادة المحاولة؛ ومحاكي الدفع في كل بيئات الاختبار يجيب في أقل من ثانية؛ ولا توجد إشارة مراقبة لـ«أكثر من خصم ناجح للطلب الواحد». وبنود العمل كلها للإصدار 7.4: معيار قبول ينص على أن إعادة المحاولة لا تخصم مرتين أبداً (مالك المنتج)، واختبار وحدة يتحقق من أن إعادة المحاولة تعيد استخدام مرجع الدفع الأصلي (المطور)، واختبار API يجيب فيه المحاكي عن الطلب الأول بعد 12 ثانية وعن إعادة المحاولة فوراً، ويُتوقع خصمٌ واحد بالضبط وحالة الطلب PAID (فريق الجودة)، ومحاكي دفع يحاكي الاستجابات البطيئة ويعامل مرجع الدفع المكرر، كما يفعل المزوّد، على أنه الدفعة نفسها (فريق الجودة)، وتنبيه على أي طلب له أكثر من خصم ناجح (فريق العمليات).
- بعد إعلان الحادثة استغرق التخفيف عشرين دقيقة، أما الوقاية فاحتاجت إلى متطلب واختبارين وقدرة جديدة في بيئة الاختبار وتنبيه.
- قبل الإصلاح شُغّل اختبار API على الإصدار 7.3 ففشل بخصمين، ومع الإصلاح نجح. واختبار الانحدار الذي لم يفشل قط أمام العيب لا يثبت شيئاً عنه.
- تستهدف الاختبارات الشرطَ، أي مزوّداً بطيئاً تتبعه إعادة محاولة، لا الطلبات بعينها من الحادثة؛ لذلك تحمي أيضاً كل مسار آخر يستخدم وحدة الدفع نفسها.
INC-0412 Customers charged twice for one order after release 7.3 (fictional)
Impact 37 orders charged twice; all refunded the same day; no data lost
Timeline all times UTC+3
09:40 Release 7.3 deployed: payment client timeout 30 s -> 10 s
09:58 First duplicate charge (found later in the payment logs)
11:05 First customer complaint to support
11:30 Incident declared; payments team and QA join
11:50 Mitigated: timeout back to 30 s by configuration; no new duplicates
15:00 All duplicate charges refunded
Detection by customers, 67 minutes after the first duplicate; no alert fired
Contributing causes (no individuals named)
- A retry after a timeout sends a new payment reference, so the provider
cannot recognise it as the same payment.
- The payment requirement said nothing about retries.
- The payment mock in every test environment answers in under 1 s,
so the timeout-and-retry path never ran in any test.
- No monitoring signal for "more than one successful charge per order".
Action items owner due
1 Acceptance criterion: a retried payment never charges twice PO 7.4
2 Unit test: a retry reuses the original payment reference dev 7.4
3 API test: the mock answers the first call after 12 s, the
retry at once; exactly one charge, order status PAID QA 7.4
4 Payment mock simulates slow answers and, like the provider,
treats a repeated payment reference as the same payment QA 7.4
5 Alert on any order with more than one successful charge ops 7.4جرّبها: محوّل الطوابع الزمنية جرّبها: حاسبة الفرق بين التواريخ
أخطاء شائعة
- كتابة المراجعة حول شخص («نسي المطور») بدلاً من الظروف التي جعلت الخطأ ممكناً.
- إضافة اختبار انحدار يعيد طلب العميل نفسه بدلاً من الشرط الكامن وراء الإخفاق.
- عدم تشغيل الاختبار الجديد على النسخة المعيبة قط، فلا يعرف أحد هل كان سيكشف الحادثة.
- وضع كل فحص جديد في اختبار واجهة شامل وبطيء، بينما يصل اختبار الوحدة أو اختبار API إلى الفرع المعيب أسرع.
- اعتبار «إضافة مزيد من الاختبارات» الإجراء الوحيد، مع أن الفجوة قد تكون في المتطلب أو البيئة أو المراقبة.
- ترك بنود العمل بلا مالك ولا موعد، فلا تُنجز أبداً.
من منظور ضمان الجودة
ينضم المختبِر عادةً بعد التخفيف، لكنه يستطيع الاستعداد فوراً: أي الاختبارات شُغّلت على الإصدار، وفي أي بيئة، وبأي بيانات. وفي المراجعة اطرح أسئلة الفجوة بهدوء وأدرج فيها عملية الاختبار نفسها؛ فعبارة «لم يكن بوسع اختباراتنا رؤية هذا لأن المحاكي لا تنتهي مهلته أبداً» نتيجةٌ عن النظام، لا اعتراف بذنب.
بعد ذلك اربط في أداة التتبع بين الحادثة والعيب وحالات الاختبار الجديدة والمتطلب المعدّل، وتحقق في الإصدار التالي من إغلاق بنود العمل. وراجع قائمة العيوب التي تسرّبت إلى الإنتاج كل بضعة أشهر: فتكرار فجوات من نوع واحد، كالمناطق الزمنية أو إعادة المحاولة، مُدخَلٌ لتحليل المخاطر ولاستراتيجية الاختبار.
تمرين عملي
حوّل حادثة تخفيضات خاطفة إلى اختبارات
الحادثة (افتراضية): أُعلن أن تخفيضات خاطفة (Flash Sale) تستمر حتى نهاية يوم 30 سبتمبر بتوقيت الرياض (UTC+3). قارن الخادم وقت الانتهاء بالوقت الحالي بتوقيت UTC، فظل سعر التخفيض سارياً ثلاث ساعات زائدة، حتى 02:59:59 يوم 1 أكتوبر بتوقيت الرياض. ولاحظ فريق المالية ذلك صباح اليوم التالي. وكل الاختبارات المؤتمتة تعمل على أجهزة التكامل المستمر (CI) المضبوطة على UTC، واستخدمت اختبارات التخفيضات تاريخين: قبل الانتهاء بيوم وبعده بيوم.
تقول مسودة المراجعة: «نسي المطور التحويل إلى توقيت الرياض» و«كان على فريق الجودة أن يختبر ذلك». أعد صياغة الجملتين دون لوم، وصنّف فجوات الاختبار، وصمّم اختبارات الانحدار، وسمِّ إجراءً واحداً على الأقل ليس اختباراً.
- أعد صياغة الجملتين اللائمتين بوصفهما عبارتين عن النظام والعملية.
- صنّف فجوات الاختبار مستخدماً فئات هذا الدرس.
- صمّم اختبارَي انحدار على الأقل، مع المستوى والأوقات المدخلة بالضبط والنتائج المتوقعة.
- أضف الإجراءات التي ليست اختبارات، واذكر كيف ستثبت أن الاختبارات الجديدة تكشف العيب.
إظهار الإجابة النموذجية
الصياغة دون لوم: «قارن فحص انتهاء التخفيضات وقتَ نهاية مقصوداً بتوقيت الرياض بساعة الخادم بتوقيت UTC، ولا يحدد أي متطلب أو قائمة مراجعة المنطقة الزمنية لتواريخ التخفيضات». و«استخدمت اختبارات التخفيضات تواريخ تبعد يوماً كاملاً عن الانتهاء، وكل الاختبارات تعمل بتوقيت UTC، فلم يكن ممكناً أن يظهر فرق الساعات الثلاث في أي اختبار».
فجوات الاختبار: شرط اختبار غائب، لأن المتطلب لا يذكر المنطقة الزمنية؛ وحالة اختبار غائبة، لأنه لم تُختبر قيم حدّية حول لحظة انتهاء التخفيضات؛ وبيئة غير واقعية، لأن كل الاختبارات تعمل بتوقيت UTC؛ وفجوة رصد، لأن المالية، لا المراقبة، هي من اكتشف المشكلة.
اختبارات الانحدار: اختبار وحدة بساعة مثبّتة (يضبط فيه الاختبار الوقت الحالي بدلاً من قراءة الوقت الحقيقي)، يُحتسب فيه سعر التخفيض عند 20:59:59 UTC يوم 30 سبتمبر (أي 23:59:59 بتوقيت الرياض) والسعر العادي عند 21:00:00 UTC (أي منتصف الليل بتوقيت الرياض)؛ واختبار API يضبط ساعة بيئة الاختبار على 21:00:00 UTC يوم 30 سبتمبر، ويطلب سعر المنتج، ويتوقع السعر العادي؛ وتشغيل الحزمة مرة أخرى والمنطقة الزمنية للجهاز مضبوطة على Asia/Riyadh، على أن تطابق نتائجه نتائج التشغيل بتوقيت UTC، فيثبت ذلك أنها لا تعتمد على منطقة الخادم.
إجراءات أخرى: ذكر المنطقة الزمنية في متطلب التخفيضات، وتنبيه على أي طلب احتُسب بسعر التخفيض بعد وقت انتهائه، ومراجعة قواعد التواريخ الأخرى، مثل القسائم والمواعيد النهائية للتوصيل، بحثاً عن النمط نفسه. ولإثبات الاختبارات شغّلها على النسخة المعيبة، حيث يبقى سعر التخفيض عند 21:00:00 UTC فيفشل الاختبار، ثم على الإصلاح حيث ينجح.
أسئلة شائعة
هل تحتاج كل حادثة إلى مراجعة ما بعد الحادثة كاملة؟
لا. اتفقوا على المعايير مسبقاً، مثل أثر يراه المستخدمون يتجاوز حداً معيناً، أو فقدان أي بيانات، أو تراجع عن إصدار أو تدخل يدوي آخر، أو وقت حلّ طويل، أو مشكلة لم تكشفها المراقبة. والحوادث الأصغر تكفيها مراجعة مكتوبة قصيرة، لكن عدة حوادث صغيرة متشابهة معاً تستحق مراجعة كاملة.
هل يعني «دون لوم» أن لا أحد مسؤول؟
لا. لا يُعاقَب أحد على خطأ صادق ارتكبه بالمعلومات التي كانت لديه، لكن لكل بند عمل مالكاً مسمّى وموعداً، والفريق مساءَل عن إنجازها. وغياب اللوم هو ما يجعل الناس يصفون قراراتهم بصدق، وعلى ذلك يعتمد التحليل.
هل يجب أن تنتهي كل حادثة باختبار مؤتمت جديد؟
الحادثة التي سببها عيب تستحق عادةً اختبار انحدار واحداً على الأقل في أدنى مستوى يمكنه كشفها. أما إذا كان السبب السعةَ أو انقطاع خدمة طرف ثالث أو تغييراً في الإعدادات، فقد يكون الإجراء الأنسب تنبيهاً أو فحصاً للإعدادات أو بنداً في قائمة فحص الإصدار. وفي كل الأحوال سجّل القرار.
ما العلاقة بين مراجعة ما بعد الحادثة وتحليل السبب الجذري؟
تحليل السبب الجذري (Root Cause Analysis)، مثل لماذا الخمسة (5 Whys) أو مخطط عظمة السمكة (Fishbone) الموصوفين في دليل فرز العيوب، أسلوبٌ يُستخدم داخل مراجعة ما بعد الحادثة للوصول من الإخفاق إلى أسبابه. أما المراجعة فأوسع: فهي تسجّل أيضاً الأثر والجدول الزمني والرصد والتخفيف، وتجد عادةً عدة أسباب مساهمة لا سبباً واحداً، وتنتهي بإجراءات لكلٍّ منها مالك.
المراجع
- Postmortem Culture: Learning from Failure — Site Reliability Engineering (John Lunney and Sue Lueder)مراجعات ما بعد الحوادث الخالية من اللوم: أيّ الحوادث تستدعيها، وما الذي تسجّله — الأثر والأسباب الجذرية وإجراءات المتابعة — ولماذا يُستبعد منها اللوم.
- ISTQB Certified Tester Foundation Level (CTFL) v4.0المنهج التأسيسي لاختبار البرمجيات: مستويات الاختبار وأنواعه وتقنيات تصميم الاختبارات وإدارة الاختبار والأدوات.
- ISTQB Glossaryالتعريفات القياسية لمصطلحات الاختبار — حالة الاختبار واختبار الانحدار والخطورة والأولوية وتحليل القيم الحدّية وغيرها.
تدرّب بأدوات متقن
ولّد سيناريوهات اختبار الانحدار من وصف التغيير وقائمة الوحدات المتأثرة والمرتبطة.
ولّد حالات اختبار منظّمة (المعرّف والعنوان والشروط المسبقة والخطوات والنتيجة المتوقّعة والأولوية) من وصف الميزة وقائمة الحقول.
حوّل التاريخ والوقت بين المناطق الزمنية (الرياض، عمّان، دلهي، UTC، نيويورك، لندن…).
حوّل الطوابع الزمنية (ثوانٍ، ميلي ثانية، ميكرو ثانية) إلى تواريخ مقروءة وبالعكس، بأي منطقة زمنية.
احسب الفرق الدقيق بين تاريخين بالسنوات والأشهر والأيام والساعات والوحدات الإجمالية.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.