كل المقالات
QA AutomationCI-CDMockingDocker

Shift Left Testing — ليش نقلنا الاختبار من الآخر للأول

بدأنا بأتمتة E2E على الـ Staging: بطيئة، Flaky، وتشغيلها باليد. الـ Shift Left غيّر المعادلة كلها — كيف صار، وشو المهارات اللي بيطلبها منك.

5 دقائق قراءة

أول ما إجت الأتمتة، حطّينا الاختبارات في آخر السلسلة: التطوير يخلص، ينزل على الـ Staging، وبعدين نشغّل الاختبارات.

واشتغلت — لكن معها إجت مجموعة أوجاع كل واحد اشتغل بهذاك الوقت بيعرفها. الـ Shift Left هو الحل اللي طلع من هذه الأوجاع بالذات.

كيف بدأت أتمتة الاختبار

الصورة كانت هيك تقريباً عند الجميع، ولسا هيك في كثير شركات ودول لليوم:

  • Selenium مع Java — الثنائي الأشهر بلا منازع
  • مشروع منفصل تماماً، بـ Repository لحاله، بعيد عن كود المنتج
  • الاختبارات بتدور على بيئة حقيقية زي الـ Staging
  • والتشغيل يدوي: المختبِر بيفتح المشروع وبيضغط Run

وكانت نقلة كبيرة فعلاً. لأول مرة صار عنا Regression بيدور بليلة بدل أسبوع. بس مع الوقت، بانت المشاكل.

الأوجاع اللي عاشها الكل

الاختبارات كانت Flaky. بتنجح مرة وبتفشل مرة، وبنفس الكود. أحياناً السبب البيئة نفسها — الخدمة بطيئة أو راجعة غلط — وأحياناً الاختبار نفسه مكتوب بشكل هش.

بيانات الاختبار كانت كابوس. بدك مستخدم بحالة معيّنة، وطلب بوضع معيّن. وبالشركات الكبيرة هذه لحالها كانت معركة: من بيعمل المستخدمين؟ ومن بينضّفهم بعدين؟ وشو بيصير لما حدا ثاني يستعمل نفس المستخدم بنفس الوقت؟

التشغيل ضل يدوي، والصيانة قبل كل تشغيل. كل تغيير بالواجهة بيكسّر Locators، فقبل ما تشغّل لازم تروح تصلّح.

كل شي كان E2E. ما في مستويات — أي فحص، مهما كان صغير، بيمرق عبر النظام كله.

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

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

إجا الـ Shift Left

الفكرة ببساطة: بدل ما تفحص بالآخر، انزل بالفحص لتحت وللأول — على مستوى الوحدة (Unit) والتكامل (Integration)، وقت ما الخطأ لسا رخيص وسهل تلاقيه.

حتى هذا يصير، طلعت أدوات وممارسات غيّرت شكل الشغل:

افصل الواجهة عن الـ Backend

بدل ما تفحص الواجهة وهي موصولة بكل الخدمات الحقيقية، بتفحصها مقابل Mock Server بيرجّع الردود اللي إنت بدك ياها. النتيجة الجانبية كانت الأهم: صار ممكن تكتب هذه الاختبارات بنفس لغة الواجهة، وبنفس الـ Repository تبعها.

هذه النقطة لحالها حلّت نص المشكلة. الاختبار صار يعيش جنب الكود اللي بيفحصه، فأي تغيير بيكسر الاختبار بيبان بنفس الـ Pull Request — مش بعد أسبوع بمشروع ثاني.

وافصل الـ Backend كمان

نفس المنطق بالضبط: تفحص الـ Backend لحاله، مع قاعدة بيانات مؤقتة بالذاكرة بتتولد وقت التشغيل وبتنمسح بعده، وبيانات بتزرعها إنت (Seeding) بدل ما تستنجد بمستخدمين جاهزين على بيئة مشتركة.

وهيك اختفى سؤال «من بيعمل مستخدمين الاختبار؟» — إنت بتعملهم، بكل تشغيلة، ومن الصفر.

وهون ولد الـ CI/CD

لما صار كل شي بمكان واحد — الكود والاختبارات والـ Mocks — صار ممكن على أي جهاز تشغّل السلسلة كلها: تنصب التطبيق، تعمل Mock لكل شي خارجي بيحتاجه، وتشغّل الاختبارات.

بدك مستخدمين؟ اعملهم Mock. بدك رد معيّن من خدمة؟ اعمله Mock.

وهذا اللي خلّى الاختبارات:

  • مستقرة — ما في بيئة مشتركة حدا ثاني بيعبث فيها
  • سريعة — ثواني بدل ساعات
  • وأهم شي: بتدور لحالها على الـ Pipeline، على كل Pull Request، بلا ما حدا يضغط زر

شكل الهرم بعد الـ Shift Left

E2E أهم المسارات فقط — ١٠٪ Integration هون معظم تغطيتك Unit الأساس، وأسرع شي بيدور

القاعدة العملية: ٩٠٪ من تغطيتك على مستوى الوحدة والتكامل، و١٠٪ فقط E2E — ومحصورة بأهم المسارات: تسجيل الدخول، الشراء، الدفع. المسارات اللي لو وقعت، وقع المنتج معها.

شو بيطلب منك الـ Shift Left كمختبِر

هذا مش تغيير بالأدوات بس — هو تغيير بالمهارات:

المهارة ليش بتحتاجها
الـ Mocking وخوادم الـ Mock كل الفكرة قايمة عليها: تعزل اللي بتفحصه عن اللي مش بتفحصه
Docker الأداة اللي انفجر استعمالها بهذا العصر — بتخليك تشغّل أي تطبيق على أي جهاز بنفس الشكل بالضبط
تصميم الاختبار تعرف شو بينفحص على أي مستوى، وتقاوم إغراء إنك تفحص كل شي E2E
الـ Synthetic Transactions اختبارات بتدور على الـ Production نفسه لأهم المسارات

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

وهيك بيصير عندك طرفين مغطّيين: قبل ما ينزل الكود، وبعد ما ينزل.

مثال صغير بيوضّح الفكرة كلها

خلينا نقول في خلل بحساب الخصم: لما تكون قيمة الطلب صفر، بيطلع الخصم رقم سالب.

بالطريقة القديمة: الخلل بيوصل للـ Staging، وبتمسكه باختبار E2E بعد أسبوع. الاختبار بيقولك «صفحة الدفع بتعرض رقم غلط» — وبس. بعدها لازم حدا يفتح الـ Logs، ويتتبّع الطلب، ويوصل للخدمة المسؤولة، ويلاقي الدالة. نص يوم على الأقل، وبين كذا شخص.

بالـ Shift Left: اختبار وحدة على دالة الخصم بيفشل خلال ثانيتين، على جهاز المطوّر، قبل ما الكود يوصل حتى للـ Pull Request. ورسالة الفشل بتقولك اسم الدالة والقيمة المتوقعة والقيمة اللي رجعت.

نفس الخلل بالضبط. الفرق وين مسكته، وهذا الفرق بيتضاعف كل ما نزلت أعمق بالسلسلة.

بالنهاية

الـ Shift Left مش إنك تفحص بدري وخلص. هو إنك تنقل الفحص لأرخص مكان ممكن تلاقي فيه الخطأ. الخطأ اللي بتمسكه باختبار وحدة بيكلّفك دقايق؛ نفس الخطأ لما يوصل للـ Production بيكلّفك اجتماعات وتذاكر واعتذارات.

ولاحظ نمط بيتكرر: كل نقلة بتاريخ الاختبار — من اليدوي للأتمتة، ومن الأتمتة للـ Shift Left — ما ألغت المختبِر، بس رفعت سقف المهارة المطلوبة منه. اللي تعلّم الـ Mocking والـ Docker وتصميم الاختبار وقت ما طلعوا، صار هو اللي بيصمّم النظام كله اليوم.

والسقف رح يرتفع مرة ثانية هسا. بس هذه قصة مقال ثاني.

بدك تتعمّق أكثر؟

المقال هون بيعطيك الفكرة. الدورات بتاخدك من الصفر لحد ما تشتغل فيها فعلياً.

شوف الدورات