كانت واجهاتنا تبدو مثالية على شاشاتنا فقط: كيف أنقذنا ‘الاختبار البصري الآلي’ من جحيم الأخطاء غير المرئية؟

يا جماعة الخير، السلام عليكم ورحمة الله.

اسمحولي اليوم أحكيلكم قصة صارت معي ومع فريقي قبل كم سنة، قصة علّمتنا درس قاسي لكنه ثمين. كنا وقتها شغالين على مشروع كبير لعميل مهم، تطبيق ويب مع واجهات عصرية وتفاعلية. بعد أسابيع من السهر والتعب، أطلقنا نسخة تجريبية من ميزة جديدة كنا فخورين فيها جدًا. على شاشاتنا، شاشات الماك بوك العريضة واللامعة، كان كل شيء بيبدو “بيرفكت”، زي ما بنحكي… كل بكسل في مكانه، والألوان متناسقة، والحركات سلسة.

أرسلنا الإيميل للعميل واحنا بنستنى عبارات المديح والشكر. لكن الرد إجا زي الصاعقة. إيميل غاضب مع لقطة شاشة (Screenshot) من جهازه. الصورة كانت كارثية! الأزرار متداخلة، والنصوص طالعة برة مربعاتها، وجزء من القائمة الرئيسية مختفي تمامًا. العميل كتب جملة واحدة قتلتنا: “هل تختبرون ما ترسلونه لي؟”.

المشكلة؟ العميل كان بيستخدم نظام ويندوز مع متصفح مختلف وبشاشة ذات دقة أقل. كل اختباراتنا الوظيفية (Functional Tests) كانت ناجحة 100%. الكود كان “يعمل”، لكن الواجهة كانت “محطمة”. يومها، أدركنا أننا كنا نعيش في كذبة، وأن واجهاتنا كانت مثالية فقط في عيوننا وعلى شاشاتنا. كنا غارقين في جحيم الأخطاء غير المرئية، وكان لازم نلاقي حل.

ما هو الاختبار البصري (Visual Testing)؟ ولماذا هو ليس رفاهية؟

ببساطة شديدة، الاختبار البصري الآلي، أو ما يُعرف بـ (Visual Regression Testing)، هو عملية تهدف للتأكد من أن واجهة المستخدم (UI) تبدو بالشكل الصحيح للمستخدم النهائي بعد كل تغيير في الكود. هو أشبه بلعبة “أوجد الفروقات” لكن الكمبيوتر هو من يلعبها بدقة متناهية.

الفكرة بسيطة في جوهرها:

  1. التقاط صورة أساس (Baseline): في المرة الأولى، نأخذ “لقطة مرجعية” لكل مكون أو صفحة في التطبيق وهي في حالتها المثالية. هذه الصور تصبح هي الحقيقة المطلقة لدينا.
  2. المقارنة بعد التغيير: بعد أن يقوم أي مطور بتعديل الكود (سواء كان تعديل CSS بسيط أو إضافة ميزة كبيرة)، يقوم نظام آلي بأخذ لقطة شاشة جديدة لنفس المكونات.
  3. كشف الفروقات: يقوم النظام بمقارنة الصورة الجديدة بالصورة المرجعية بكسل ببكسل. إذا وجد أي اختلاف، مهما كان صغيراً، يقوم بتعليم هذا الاختلاف وعرضه على المطور.
  4. القرار البشري: هنا يتدخل المطور أو المصمم. هل هذا التغيير مقصود (مثلاً، تغيير لون زر)؟ إذاً، يتم قبول الصورة الجديدة لتصبح هي الصورة المرجعية. هل التغيير غير مقصود (مثلاً، تداخل عنصرين)؟ إذاً، هذا “خطأ بصري” (Visual Bug) يجب إصلاحه فوراً قبل أن يصل للمستخدم.

لماذا اختباراتنا التقليدية فشلت في حمايتنا؟

قد يسأل سائل: “أنا أكتب Unit Tests و E2E Tests باستخدام Cypress أو Selenium، أليس هذا كافياً؟”. الجواب، للأسف، لا.

  • اختبارات الوحدة (Unit Tests): تختبر منطق العمل (Business Logic) في دالة معينة. هي لا “ترى” الواجهة على الإطلاق.
  • الاختبارات الشاملة (E2E Tests): يمكنها أن تتأكد من وجود زر على الشاشة (cy.get('button').should('exist'))، ويمكنها النقر عليه. لكنها لا تستطيع أن تخبرك إذا كان هذا الزر نصفه مختفٍ خلف عنصر آخر، أو أن لونه تغير من الأزرق إلى الأحمر بالخطأ، أو أن النص بداخله قد خرج عن حدوده. هي “عمياء” من الناحية البصرية.

الاختبارات الوظيفية تتأكد من أن التطبيق يعمل بشكل صحيح. الاختبارات البصرية تتأكد من أنه يبدو بشكل صحيح. وكلاهما ضروري لتجربة مستخدم ممتازة.

لنكن عمليين: كيف نبدأ مع الاختبار البصري؟

الكلام النظري جميل، لكن “كيف أطبق هذا يا أبو عمر؟”. حسنًا، لننزل إلى الميدان. هناك العديد من الأدوات الرائعة في السوق، بعضها مدفوع مثل Percy و Applitools، وبعضها مفتوح المصدر مثل BackstopJS. سأركز على سير عمل شائع جداً يجمع بين Storybook و Percy لأنه فعال للغاية.

الخطوة الأولى: اعزل مكوناتك مع Storybook

قبل أن تختبر واجهاتك، يجب أن تتمكن من عرضها بشكل منظم. هنا يأتي دور Storybook. هو أداة تسمح لك ببناء وعرض مكونات الواجهة (Buttons, Forms, Cards) بشكل معزول عن بقية التطبيق. هذا يجعل اختبارها بصريًا أسهل وأسرع ألف مرة.

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

الخطوة الثانية: دمج أداة الاختبار البصري (مثال: Percy)

بمجرد أن يصبح لديك Storybook، فإن إضافة أداة مثل Percy تصبح سهلة للغاية.

1. قم بتثبيت الحزم اللازمة:

npm install --save-dev @percy/cli @percy/storybook

2. الآن، لتشغيل الاختبارات، كل ما عليك هو بناء Storybook الخاص بك ثم تشغيل أمر Percy:

# أولاً، ابنِ نسخة ثابتة من Storybook
npm run build-storybook

# ثانياً، شغّل Percy ليلتقط الصور ويقارنها
npx percy storybook ./storybook-static

بالطبع، ستحتاج إلى إعداد حساب على Percy والحصول على PERCY_TOKEN الخاص بمشروعك. لكن العملية برمتها لا تستغرق أكثر من 10 دقائق.

الخطوة الثالثة: الأتمتة الكاملة مع CI/CD

الجمال الحقيقي يكمن في الأتمتة. لا نريد أن نتذكر تشغيل هذه الأوامر يدويًا. نريدها أن تعمل تلقائيًا مع كل Pull Request جديد. هنا يأتي دور خدمات مثل GitHub Actions.

يمكنك إضافة ملف بسيط إلى مشروعك (مثلاً: .github/workflows/visual-tests.yml) ليقوم بالعمل نيابة عنك:

name: 'Visual Tests'

on: pull_request

jobs:
  visual-regression:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install Dependencies
        run: npm install

      - name: Build Storybook
        run: npm run build-storybook

      - name: Run Percy Visual Tests
        run: npx percy storybook ./storybook-static
        env:
          PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

الآن، ماذا يحدث؟

  1. يقوم المطور بإنشاء Pull Request.
  2. تعمل GitHub Actions تلقائيًا.
  3. تقوم بتشغيل Percy، الذي يلتقط لقطات شاشة جديدة.
  4. يضيف Percy تعليقًا على الـ Pull Request يظهر فيه “فحص بصري” مع رابط للنتائج.
  5. يمكن لمراجع الكود (Code Reviewer) النقر على الرابط ورؤية الفروقات البصرية جنبًا إلى جنب. إذا كان هناك خطأ، يطلب تعديلاً. إذا كانت التغييرات مقصودة، يضغط على “Approve” بنقرة واحدة.

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

نصائح من خبرة أبو عمر 🧔

  • ابدأ صغيراً: لا تحاول اختبار كل شاشات تطبيقك دفعة واحدة. ابدأ بالمكونات الحرجة والمشتركة: الأزرار، حقول الإدخال، الشريط العلوي (Header)، التذييل (Footer). ثم توسع تدريجياً.
  • تعامل مع المحتوى الديناميكي: ماذا لو كان لديك مكون يعرض الوقت الحالي؟ ستفشل الاختبارات في كل مرة. معظم الأدوات تسمح لك بتجاهل مناطق معينة في الصورة أو إخفاء عناصر محددة باستخدام CSS بسيط. تعلم كيفية استخدام هذه الميزات.
  • ضع هامش خطأ (Threshold) بحذر: بعض الأدوات تسمح بوجود نسبة اختلاف بسيطة (مثلاً 1%) لتجاوز الفروقات الطفيفة في عرض الخطوط بين الأنظمة (Anti-aliasing). استخدمها بحذر شديد، فالشيطان يكمن في التفاصيل (والبكسلات).
  • الاختبار البصري مسؤولية الفريق: هذه ليست مهمة قسم الجودة (QA) فقط. المطورون والمصممون يجب أن يشاركوا في مراجعة التغييرات البصرية. هذا يعزز التواصل ويضمن الحفاظ على تناسق التصميم.
  • لا تستبدل الاختبار اليدوي، بل عززه: الاختبار البصري الآلي هو شبكة أمان رائعة، لكنه لن يكتشف أخطاء تجربة المستخدم المعقدة. لا يزال هناك مكان للاختبار اليدوي الاستكشافي.

الخلاصة: من الجحيم إلى الثقة بالنفس ✅

التحول إلى الاختبار البصري الآلي لم يكن مجرد إضافة أداة جديدة، بل كان تغييراً في العقلية. لقد انتقلنا من حالة القلق الدائم مع كل عملية نشر (Deployment) إلى حالة من الثقة والهدوء. لم نعد نخشى تلك الأخطاء “غير المرئية” لأننا بنينا نظاماً يكشفها لنا قبل أن يراها أي شخص آخر.

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

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

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

4 يونيو، 2026 قراءة المزيد
الحوسبة السحابية

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

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

4 يونيو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كانت مهمتي البرمجية للاختبار مجرد كود: كيف أنقذني توثيق القرارات من جحيم الصمت بعد المقابلة؟

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

4 يونيو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كان كل خادم لدينا ‘ندفة ثلج’ فريدة: كيف أنقذنا ‘الكود كبنية تحتية’ (IaC) من جحيم الانجراف اليدوي؟

في هذه المقالة، أشارككم قصة حقيقية من قلب المعركة التقنية مع "خوادم ندفات الثلج" الفوضوية. سنغوص في مفهوم "الكود كبنية تحتية" (IaC) وكيف أن أدوات...

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

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

4 يونيو، 2026 قراءة المزيد
البودكاست