الإزاحة لليسار والإزاحة لليمين

تصف الإزاحة لليسار (Shift-left) والإزاحة لليمين (Shift-right) موضع الاختبار على الخط الزمني للتغيير. فالإزاحة لليسار تنقل الاختبار إلى وقت أبكر: مراجعة قصة المستخدم، والاتفاق على اختبارات القبول قبل البرمجة، وتشغيل التحليل الساكن على كل طلب دمج (Pull request). أما الإزاحة لليمين فتمدّه إلى ما بعد الإصدار: متابعة إشارات بيئة الإنتاج، وإظهار الميزة لـ⁦5%⁩ من المستخدمين أولاً، وإجراء تجارب مضبوطة.

فالمختبِر الذي يسأل في جلسة التحسين (Refinement): «هل يُحسب الخصم قبل ضريبة القيمة المضافة أم بعدها؟» يزيح الاختبار لليسار، والمختبِر نفسه حين يقارن معدل أخطاء الإطلاق الكناري ببقية المستخدمين بعد الإصدار يزيحه لليمين. ولا يحلّ أيٌّ منهما محل الاختبار الذي يقع بينهما.

لماذا يهم

العيب الذي يُكتشف في مراجعة القصة يكلّف محادثة. أما بعد الإصدار فيكلّف العيب نفسه إصلاحاً وإعادة نشر ووقتاً من فريق الدعم، وأحياناً مبالغ مستردة وشيئاً من ثقة المستخدمين. والإزاحة لليسار تمنع العيوب وتكشف ما تبقى منها والتغيير ما زال صغيراً.

لكن لا توجد بيئة اختبار تطابق بيئة الإنتاج تماماً: الحركة الحقيقية والبيانات الحقيقية وكل جهاز وكل خدمة خارجية. بعض الإخفاقات لا يظهر إلا هناك، ومن دون ممارسات الإزاحة لليمين يكون المستخدمون أول من يلاحظها. وبالنسبة إلى المختبِر، لم يعد الاختبار مرحلة في النهاية، بل صار عملاً يمتد على دورة الحياة كلها.

الإزاحة لليسار: اختبر قبل كتابة الكود وأثناءها

يصف منهج ISTQB للمستوى التأسيسي (CTFL الإصدار ⁦4.0⁩) الإزاحة لليسار بأنها اختبار في وقت أبكر، دون انتظار كتابة الكود أو دمج المكوّنات، ويؤكد أنها لا تعني إهمال الاختبار في المراحل اللاحقة. وهي الصورة العملية لمبدأ أن الاختبار المبكر يوفّر الوقت والمال. وإلى جانب الممارسات أدناه، يذكر المنهج التكامل المستمر (CI)، والأفضل منه التسليم المستمر (CD)، لما يوفّرانه من تغذية راجعة سريعة على كل تغيير كما في الدرس السابق، وبدء الاختبار غير الوظيفي، كاختبار الأداء، من مستوى المكوّن حيثما أمكن. ويذكر ثمنها أيضاً: تدريباً وجهداً إضافيين في البداية يُتوقع أن يُستردّا لاحقاً، وتحتاج الإزاحة لليسار إلى أصحاب مصلحة مقتنعين بها ومساندين لها.

  • المراجعات المبكرة: يراجع المختبِرون قصص المستخدم ومعايير القبول والتصاميم من منظور الاختبار. وهذا اختبار ساكن يكشف الغموض والنقص والتناقض قبل أن يوجد أي كود.
  • التطوير الموجَّه بالاختبار (TDD): يكتب المطوّر اختبار وحدة يفشل، ثم يكتب من الكود ما يكفي لنجاحه فقط، ثم يعيد هيكلة الاثنين (Refactoring)، أي يحسّن بنيتهما دون أن يغيّر ما يفعلانه.
  • التطوير الموجَّه باختبارات القبول (ATDD): تُشتق اختبارات القبول من معايير القبول قبل بناء الميزة. وفي التطوير الموجَّه بالسلوك (BDD) تُكتب هذه الأمثلة بصيغة Given/When/Then، كالسيناريوهين أدناه.
  • التحليل الساكن: أدوات تفحص الكود المصدري دون تشغيله، وتُبلغ عن المتغيرات غير المعرَّفة والكود الذي لا يمكن الوصول إليه ومخالفات معايير البرمجة وبعض الثغرات الأمنية، وتعمل عادةً على كل طلب دمج ضمن التكامل المستمر (CI).
Feature: رمز الخصم عند إتمام الشراء

  Scenario: رمز نسبة مئوية صالح يخفض الإجمالي قبل الضريبة
    Given سلة إجماليها 150.00 ريال قبل ضريبة القيمة المضافة
    And الرمز الفعال "SAVE10" يمنح خصم 10%
    When يطبّق المتسوق الرمز "save10"
    Then يكون الخصم 15.00 ريال
    And يكون الإجمالي قبل الضريبة 135.00 ريال

  Scenario: رمز منتهي الصلاحية يُرفض
    Given انتهت صلاحية الرمز "WINTER25" أمس
    When يطبّق المتسوق الرمز "WINTER25"
    Then تظهر الرسالة «انتهت صلاحية هذا الرمز»
    And لا يتغير الإجمالي

جرّبها: مولّد معايير القبول جرّبها: المتطلبات ← حالات اختبار

الإزاحة لليمين: واصل الاختبار بعد الإصدار

الإزاحة لليمين مصطلح شائع في الصناعة وليس من مصطلحات المستوى التأسيسي في ISTQB، وبعض الفرق تسمّي جزءاً منه «الاختبار في الإنتاج». فبيئة الإنتاج وحدها فيها الحركة الحقيقية والبيانات الحقيقية وكل الأجهزة، لذا فالهدف هو الحدّ من ضرر العيوب التي تتسرّب ومعرفة ما فات الاختبار المبكر، لا الاختبار على المستخدمين بدلاً من الاختبار قبل وصول التغيير إليهم.

  • المراقبة (Monitoring): لوحات متابعة وتنبيهات تعكس تجربة المستخدمين الفعلية. والإشارات الذهبية الأربع التي مرّت بك في درس DevOps للمختبِرين، وهي من كتاب SRE من Google، هي: زمن الاستجابة (Latency) أي المدة التي يستغرقها الطلب، والحركة (Traffic) أي مقدار ما يصل إلى النظام من طلبات، والأخطاء (Errors) أي معدل الطلبات الفاشلة، والتشبّع (Saturation) أي مدى امتلاء موارد النظام. وأضف إشارات الأعمال مثل عدد الطلبات في الساعة، لأن بعض العيوب لا يُطلق أي خطأ.
  • الإطلاق الكناري (Canary release): يصل التغيير أولاً إلى نسبة صغيرة من المستخدمين، وتُقارن إشاراته بمجموعة ضابطة تعمل على الإصدار القديم خلال الفترة نفسها. فإن كان أسوأ، يُتراجع عنه قبل أن يراه أغلب المستخدمين.
  • أعلام الميزات (Feature flags): يُنشر الكود الجديد مطفأً، ثم يُفعَّل لمجموعة أو لنسبة من المستخدمين دون إعادة نشر. اختبر حالتي العلم كلتيهما والانتقال بينهما.
  • تجارب A/B (A/B testing): يُشغَّل بديلان يعمل كلاهما بشكل صحيح جنباً إلى جنب على مستخدمين موزَّعين عشوائياً، ويُحكم بينهما بمقياس متفق عليه مسبقاً. يتحقق المختبِر من صحة إعداد التجربة، ويحكم مالك المنتج والمحللون على النتيجة.
  • تجارب الفوضى (Chaos experiments): يحقن الفريق عطلاً واقعياً، كتباطؤ خدمة يعتمد عليها النظام، ليختبر فرضية أن النظام يحافظ على سلوكه الطبيعي. وتبدأ التجارب صغيرة ويمكن إيقافها فوراً.

جرّبها: فاحص صحة API جرّبها: مقارنة استجابات API

مثال تطبيقي: حقل رمز الخصم من القصة إلى الإنتاج

يضيف متجر إلكتروني حقلاً لرمز الخصم في صفحة إتمام الشراء، والأسعار بالريال بمنزلتين عشريتين. ويعرض الشكل الميزة على جانبي الإصدار.

حقل رمز الخصم على جانبي إصداره: المراجعة وATDD وTDD والتحليل الساكن والتكامل المستمر قبله، وتفعيل العلم للموظفين وكناري على ⁦5%⁩ والمراقبة وتجربة A/B وتجربة فوضى بعده.
  1. قبل الإصدار: الإزاحة لليسار

    منع العيوب واكتشافها حين يكون إصلاحها رخيصاً

    1. 1مراجعة القصةحسم الجمع بين العروض وحالة الأحرف والضريبة والتقريب قبل البرمجة
    2. 2اختبارات القبول أولاًATDDأمثلة Given/When/Then متفق عليها
    3. 3اختبارات الوحدة أولاًTDD⁦10%⁩ من ⁦99.99⁩ ريال يجب أن تعطي ⁦10.00⁩
    4. 4التحليل الساكن والمراجعةاستعلام مبني من رمز الخصم المكتوب ← استعلام بمعاملات
    5. 5خط التكامل المستمرنجاح اختبارات الوحدة والواجهة البرمجية والقبول

      بوابة: النشر: في الإنتاج والعلم promo_codes مطفأ

  2. بعد الإصدار: الإزاحة لليمين

    الحدّ من الضرر والتعلّم من الاستخدام الحقيقي

    1. 6تفعيل العلم للموظفينيبدأ الإصدار للمستخدمين (الموظفون ثم ⁦5%⁩)؛ فحص دخان بحساب اختبار
    2. 7كناري: ⁦5%⁩ من المتسوقيننسب الأخطاء وزمن الاستجابة وإتمام الشراء مقارنةً بالـ⁦95%⁩ الباقين

      بوابة: لم يتحقق أي معيار للتراجع

    3. 8المراقبةعيب متسرّب: لوحة مفاتيح منصة واحدة تضيف مسافة بعد الرمزتنبيه
    4. 9تجربة A/Bحقل ظاهر مقابل رابط «لديك رمز؟»
    5. 10تجربة فوضىخدمة الخصم بطيئة: رسالة واضحة، والدفع ما زال ممكناً

عودة إلى الخطوة 2 يصبح العيب المتسرّب اختبار قبول جديداً: يُقبل الرمز المحاط بمسافات

ترتيب توضيحي: بعد الإصدار تستمر المراقبة طوال الوقت، وتُجدول التجارب بعد أن تستقر الميزة.

  • المراجعة: يسأل المختبِر هل يُجمع الرمز مع التوصيل المجاني، وهل الرموز حساسة لحالة الأحرف، وهل يُحسب الخصم قبل الضريبة وكيف يُقرَّب. وتُضاف الإجابات إلى معايير القبول.
  • ATDD وTDD: تصبح الأمثلة المتفق عليها اختبارات قبول كالسيناريوهين أعلاه (لاحظ save10 بأحرف صغيرة: اتفق الفريق على أن الرموز غير حساسة لحالة الأحرف). ويكتب المطوّر اختبارات الوحدة أولاً، ومنها اختبار يحسب ⁦10%⁩ من ⁦99.99⁩ ريال، ويجب أن تكون النتيجة ⁦10.00⁩ لا ⁦9.99⁩ وفق التقريب المتفق عليه إلى أقرب ⁦0.01⁩.
  • التحليل الساكن: تنبّه الأداة إلى استعلام يُبنى بلصق رمز الخصم الذي كتبه المتسوق مباشرةً في نص جملة SQL، مما قد يسمح لرمز خصم مصوغ بعناية بتغيير الاستعلام نفسه (حقن SQL). فيطلب المراجِع قبل الدمج استعلاماً بمعاملات (Parameterised query) يمرّر رمز الخصم بوصفه بيانات.
  • العلم والكناري: يُنشر الكود والعلم promo_codes مطفأ، ثم يُفعَّل للموظفين الذين يجرون عليه فحص دخان بحسابات اختبار، ثم لـ⁦5%⁩ من المتسوقين. وتُقارن أخطاء الخصم وزمن الاستجابة وعمليات الشراء المكتملة بالـ⁦95%⁩ الباقين بوصفها نسباً لا أعداداً خاماً، وفق معايير تراجع مكتوبة مسبقاً.
  • العيب المتسرّب: تُظهر المراقبة ارتفاع أخطاء «رمز غير صالح» على منصة جوال واحدة تضيف لوحة مفاتيحها مسافة بعد الرمز. صار الإصلاح يحذف المسافات من بداية الرمز ونهايته، وأضاف المختبِر اختبار قبول للرموز المحاطة بمسافات، فانتقلت الملاحظة إلى اليسار.
  • التجارب: تقارن تجربة A/B حقلاً ظاهراً برابط «لديك رمز؟» بعدد عمليات الشراء المكتملة، وهو المقياس المتفق عليه مسبقاً. وتُبطئ تجربة فوضى خدمة الخصم لتختبر فرضية أن صفحة الشراء، بدلاً من أن تتعلّق، تُبلغ المتسوق بتعذّر التحقق من الرمز الآن وتتيح له الدفع رغم ذلك.

جرّبها: حاسبة النسبة المئوية

الموازنة بين الجانبين

الجانبان متكاملان لا بديلان. عمل اليسار رخيص ويمنع العيوب لكنه يختبر افتراضات الفريق، وعمل اليمين يرى الواقع لكن ما يكتشفه قد وصل بالفعل إلى أحد ما. حدّد الوزن لكل تغيير بحسب المخاطر.

  • رجّح اليسار حين يكون الإخفاق خطيراً أو لا رجعة فيه: المدفوعات وترحيل البيانات والخصوصية والأمان. فالتراجع لا يعيد مبلغاً حُصِّل من العميل خطأً.
  • رجّح اليمين حين لا يجيب عن السؤال إلا الاستخدام الحقيقي: الحمل الحقيقي، والطيف الكامل من الأجهزة، والتصميم الذي يفضّله المستخدمون.
  • أغلق الحلقة: لكل عيب متسرّب، أضف الاختبار أو سؤال المراجعة أو قاعدة التحليل الساكن التي كانت ناقصة.
  • لا تختبر في الإنتاج إلا على أنظمة يملكها فريقك أو لديك إذن مكتوب باختبارها، وبحسابات اختبار، ودون بيانات شخصية حقيقية، ومع وسيلة للإيقاف فوراً.

جرّبها: مولّد الاختبار المبني على المخاطر

أخطاء شائعة

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

من منظور ضمان الجودة

في جلسة التحسين اجلس مع مالك المنتج ومطوّر (وتسمّي بعض الفرق ذلك «الأصدقاء الثلاثة» Three Amigos)، واطرح الأسئلة، واقترح أمثلة ملموسة، وحوّل المتفق عليه منها إلى اختبارات قبول. وفي طلبات الدمج اقرأ نتائج التحليل الساكن وتحقق من أن اختبارات الوحدة تغطي الأمثلة. وقبل الإصدار ساعد في كتابة خطة الإطلاق: حالات الأعلام وخطوات الإطلاق الكناري والإشارات المراقَبة ومعايير التراجع ومن يتخذ القرار.

أثناء الإطلاق راقب لوحات المتابعة مع المطوّرين، وفي الأيام التالية اقرأ تذاكر الدعم وسجلات الأخطاء. سجّل حالات الأعلام التي اختبرتها ومعايير التراجع وكل ملاحظة من الإنتاج مع الاختبار الذي أضفته لها. فهذا السجل يُري الفريق إلى أين ينبغي أن ينتقل اختباره بعد ذلك.

تمرين عملي

خطّط لجانبي الإصدار لميزة مواعيد التوصيل

المطلوب

يضيف تطبيق بقالة مواعيد للتوصيل. اقرأ قصة المستخدم أدناه وخطّط لاختبارها على جانبي الإصدار: ما الذي ستفعله قبل دمج الكود، وما الذي ستفعله بعد وصوله إلى الإنتاج.

اجعل الخطة في صفحة واحدة. ولكل نشاط على جانب اليمين، اذكر ما ستقيسه وأي نتيجة ستوقف الإطلاق.

المادة
قصة المستخدم:
بصفتي متسوقاً، أريد اختيار موعد للتوصيل عند إتمام الشراء
حتى أكون في المنزل عند وصول الطلب.

القواعد:
- مدة كل موعد ساعتان، من 09:00 إلى 21:00.
- يمكن حجز الموعد حتى 3 ساعات قبل بدايته.
- يقبل كل موعد 20 طلباً كحد أقصى.
الخطوات
  1. اكتب ثلاثة أسئلة لمراجعة القصة.
  2. اكتب اختباري قبول بصيغة Given/When/Then، أحدهما سلبي.
  3. اكتب خطة الإطلاق: العلم، ومجموعة الكناري، وثلاث إشارات للمراقبة، ومعياراً واحداً للتراجع.
  4. اكتب فرضية واحدة لتجربة فوضى، واذكر أي جانب من الإصدار سترجّحه لهذه الميزة ولماذا.
إظهار الإجابة النموذجية
الإجابة النموذجية

أسئلة المراجعة: بأي توقيت تُحدَّد أوقات المواعيد وحدّ الساعات الثلاث: المنطقة الزمنية للمتجر أم ساعة جهاز المتسوق؟ ماذا يحدث إذا حجز متسوقان آخر مكان في الموعد في اللحظة نفسها؟ ماذا يرى المتسوق إذا امتلأ الموعد أثناء الدفع؟

اختبارات القبول: بفرض أن موعد ⁦15:00–17:00⁩ فيه ⁦19⁩ طلباً والساعة ⁦11:59⁩، عندما يحجزه متسوق، فإن الحجز ينجح ويظهر الموعد ممتلئاً. وبفرض أن الساعة ⁦12:01⁩، عندما يفتح متسوق قائمة المواعيد، فإن موعد ⁦15:00–17:00⁩ لا يظهر (اختبار سلبي). أما هل يُسمح بالحجز عند الساعة ⁦12:00⁩ تماماً فسؤال آخر للمراجعة، وبعد حسمه يستطيع المطوّر كتابة هذا الحدّ اختبارَ وحدة أولاً (TDD).

خطة الإطلاق: انشر والعلم delivery_slots مطفأ، ثم فعّله للموظفين، ثم لـ⁦5%⁩ من المتسوقين. راقب أخطاء الحجز، وعدد الطلبات في كل موعد (لا يتجاوز ⁦20⁩ أبداً)، وعمليات الشراء المكتملة مقارنةً بالمجموعة الضابطة. أطفئ العلم إذا تجاوز أي موعد ⁦20⁩ طلباً، أو إذا انخفضت عمليات الشراء المكتملة عن المجموعة الضابطة بأكثر من العتبة المتفق عليها في الخطة.

فرضية الفوضى: إذا تعطلت خدمة المواعيد، يكتمل الشراء مع خيار التوصيل العادي ورسالة واضحة، ولا يضيع أي طلب. قِس عمليات الشراء المكتملة والطلبات الضائعة أثناء التجربة، وأوقفها فوراً إذا ضاع أي طلب. جرّبها في بيئة Staging أولاً، ثم على نسبة صغيرة من حركة الإنتاج.

الترجيح: الحجز الزائد وأخطاء المنطقة الزمنية مكلفة ويصعب التراجع عنها، فرجّح جانب اليسار لقواعد السعة وحدّ الحجز. أما هل يستخدم المتسوقون المواعيد أصلاً، وأي عرض للمواعيد أفضل، فهي أسئلة جانب اليمين.

أسئلة شائعة

هل الإزاحة لليمين مجرد اسم آخر للاختبار في الإنتاج؟

الاختبار في الإنتاج جزء منها، لكن الإزاحة لليمين تشمل أيضاً المراقبة والإطلاق الكناري وأعلام الميزات وتجارب A/B وتجارب الفوضى، وهي في الغالب ممارسات تراقب وتحدّ من المخاطر أكثر مما تنفّذ حالات اختبار مكتوبة. وهي تضيف دائماً إلى الاختبار قبل الإصدار ولا تحل محله أبداً.

هل تعني الإزاحة لليسار أن على المختبِر كتابة اختبارات الوحدة؟

لا. التطوير الموجَّه بالاختبار (TDD) ممارسة يقوم بها المطوّرون. والإزاحة لليسار تعني أن أنشطة الاختبار تبدأ أبكر: يقدّم المختبِر الأسئلة والأمثلة واختبارات القبول وتحليل المخاطر، ويقرأ نتائج التحليل الساكن واختبارات الوحدة. ويمكن للمختبِر الذي يبرمج أن يعمل مع المطوّرين على الاختبارات، لكن ذلك ميزة إضافية لا تعريف.

ما الفرق بين الإطلاق الكناري وتجربة A/B؟

كلاهما يقارن مجموعتين خلال الفترة نفسها (بل يصف دليل SRE العملي من Google الإطلاق الكناري بأنه في جوهره عملية اختبار A/B)، لكنهما يجيبان عن سؤالين مختلفين. يسأل الإطلاق الكناري: هل الإصدار الجديد آمن؟ فيقارن إشارات السلامة مثل الأخطاء وزمن الاستجابة بمجموعة ضابطة، لمدة تناسب وتيرة إصدارات الفريق، وينتهي بإطلاق كامل أو بتراجع. أما تجربة A/B فتسأل: أي البديلين السليمين يخدم الهدف أفضل؟ فتقارن مقياس أعمال اختير مسبقاً، وتستمر عادةً مدة أطول حتى يشارك فيها عدد كافٍ من المستخدمين.

هل يستطيع فريق صغير بلا قسم عمليات أن يطبّق الإزاحة لليمين؟

نعم، بخطوات صغيرة: فحص دخان بعد كل نشر مباشرةً، وتنبيهات على الأخطاء، وفحص صحة لنقاط النهاية الرئيسية، وعلم ميزة أو تراجع مُجرَّب للتغييرات الخطرة. أما توجيه الحركة للإطلاق الكناري وتجارب الفوضى فتحتاج إلى بنية تحتية أكبر ويمكن أن تأتي لاحقاً.

المراجع

تدرّب بأدوات متقن

ولّد معايير قبول بصيغة Given/When/Then وقائمة تحقق لتعريف الإنجاز (Definition of Done) من قصة مستخدم.

تصميم الاختبارات

حوّل قائمة متطلبات مرقّمة إلى حالات اختبار قابلة للتتبّع مع مصفوفة تربط المتطلبات بالاختبارات.

تصميم الاختبارات

افحص عدة نقاط نهاية لصحة API دفعة واحدة واحصل على الحالة وزمن الاستجابة وملخّص نجاح/فشل.

اختبار واجهات API

قارن استجابتي API (مثل بيئة التجريب مقابل الإنتاج) واحصل على قائمة بكل فرق بنيوي أو في القيم.

اختبار واجهات API

حساب النسب المئوية ونسبة التغيّر والزيادة/النقصان وكم تمثّل X من Y بالنسبة المئوية.

أدوات مساعدة

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة