يا جماعة الخير، السلام عليكم ورحمة الله.
اسمحولي اليوم أحكيلكم قصة صارت معي ومع فريقي قبل كم سنة، قصة علّمتنا درس قاسي لكنه ثمين. كنا وقتها شغالين على مشروع كبير لعميل مهم، تطبيق ويب مع واجهات عصرية وتفاعلية. بعد أسابيع من السهر والتعب، أطلقنا نسخة تجريبية من ميزة جديدة كنا فخورين فيها جدًا. على شاشاتنا، شاشات الماك بوك العريضة واللامعة، كان كل شيء بيبدو “بيرفكت”، زي ما بنحكي… كل بكسل في مكانه، والألوان متناسقة، والحركات سلسة.
أرسلنا الإيميل للعميل واحنا بنستنى عبارات المديح والشكر. لكن الرد إجا زي الصاعقة. إيميل غاضب مع لقطة شاشة (Screenshot) من جهازه. الصورة كانت كارثية! الأزرار متداخلة، والنصوص طالعة برة مربعاتها، وجزء من القائمة الرئيسية مختفي تمامًا. العميل كتب جملة واحدة قتلتنا: “هل تختبرون ما ترسلونه لي؟”.
المشكلة؟ العميل كان بيستخدم نظام ويندوز مع متصفح مختلف وبشاشة ذات دقة أقل. كل اختباراتنا الوظيفية (Functional Tests) كانت ناجحة 100%. الكود كان “يعمل”، لكن الواجهة كانت “محطمة”. يومها، أدركنا أننا كنا نعيش في كذبة، وأن واجهاتنا كانت مثالية فقط في عيوننا وعلى شاشاتنا. كنا غارقين في جحيم الأخطاء غير المرئية، وكان لازم نلاقي حل.
ما هو الاختبار البصري (Visual Testing)؟ ولماذا هو ليس رفاهية؟
ببساطة شديدة، الاختبار البصري الآلي، أو ما يُعرف بـ (Visual Regression Testing)، هو عملية تهدف للتأكد من أن واجهة المستخدم (UI) تبدو بالشكل الصحيح للمستخدم النهائي بعد كل تغيير في الكود. هو أشبه بلعبة “أوجد الفروقات” لكن الكمبيوتر هو من يلعبها بدقة متناهية.
الفكرة بسيطة في جوهرها:
- التقاط صورة أساس (Baseline): في المرة الأولى، نأخذ “لقطة مرجعية” لكل مكون أو صفحة في التطبيق وهي في حالتها المثالية. هذه الصور تصبح هي الحقيقة المطلقة لدينا.
- المقارنة بعد التغيير: بعد أن يقوم أي مطور بتعديل الكود (سواء كان تعديل CSS بسيط أو إضافة ميزة كبيرة)، يقوم نظام آلي بأخذ لقطة شاشة جديدة لنفس المكونات.
- كشف الفروقات: يقوم النظام بمقارنة الصورة الجديدة بالصورة المرجعية بكسل ببكسل. إذا وجد أي اختلاف، مهما كان صغيراً، يقوم بتعليم هذا الاختلاف وعرضه على المطور.
- القرار البشري: هنا يتدخل المطور أو المصمم. هل هذا التغيير مقصود (مثلاً، تغيير لون زر)؟ إذاً، يتم قبول الصورة الجديدة لتصبح هي الصورة المرجعية. هل التغيير غير مقصود (مثلاً، تداخل عنصرين)؟ إذاً، هذا “خطأ بصري” (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 }}
الآن، ماذا يحدث؟
- يقوم المطور بإنشاء Pull Request.
- تعمل GitHub Actions تلقائيًا.
- تقوم بتشغيل Percy، الذي يلتقط لقطات شاشة جديدة.
- يضيف Percy تعليقًا على الـ Pull Request يظهر فيه “فحص بصري” مع رابط للنتائج.
- يمكن لمراجع الكود (Code Reviewer) النقر على الرابط ورؤية الفروقات البصرية جنبًا إلى جنب. إذا كان هناك خطأ، يطلب تعديلاً. إذا كانت التغييرات مقصودة، يضغط على “Approve” بنقرة واحدة.
هذا السير في العمل يغير قواعد اللعبة. لقد تحولنا من اكتشاف الأخطاء بعد فوات الأوان إلى منعها من الحدوث في المقام الأول.
نصائح من خبرة أبو عمر 🧔
- ابدأ صغيراً: لا تحاول اختبار كل شاشات تطبيقك دفعة واحدة. ابدأ بالمكونات الحرجة والمشتركة: الأزرار، حقول الإدخال، الشريط العلوي (Header)، التذييل (Footer). ثم توسع تدريجياً.
- تعامل مع المحتوى الديناميكي: ماذا لو كان لديك مكون يعرض الوقت الحالي؟ ستفشل الاختبارات في كل مرة. معظم الأدوات تسمح لك بتجاهل مناطق معينة في الصورة أو إخفاء عناصر محددة باستخدام CSS بسيط. تعلم كيفية استخدام هذه الميزات.
- ضع هامش خطأ (Threshold) بحذر: بعض الأدوات تسمح بوجود نسبة اختلاف بسيطة (مثلاً 1%) لتجاوز الفروقات الطفيفة في عرض الخطوط بين الأنظمة (Anti-aliasing). استخدمها بحذر شديد، فالشيطان يكمن في التفاصيل (والبكسلات).
- الاختبار البصري مسؤولية الفريق: هذه ليست مهمة قسم الجودة (QA) فقط. المطورون والمصممون يجب أن يشاركوا في مراجعة التغييرات البصرية. هذا يعزز التواصل ويضمن الحفاظ على تناسق التصميم.
- لا تستبدل الاختبار اليدوي، بل عززه: الاختبار البصري الآلي هو شبكة أمان رائعة، لكنه لن يكتشف أخطاء تجربة المستخدم المعقدة. لا يزال هناك مكان للاختبار اليدوي الاستكشافي.
الخلاصة: من الجحيم إلى الثقة بالنفس ✅
التحول إلى الاختبار البصري الآلي لم يكن مجرد إضافة أداة جديدة، بل كان تغييراً في العقلية. لقد انتقلنا من حالة القلق الدائم مع كل عملية نشر (Deployment) إلى حالة من الثقة والهدوء. لم نعد نخشى تلك الأخطاء “غير المرئية” لأننا بنينا نظاماً يكشفها لنا قبل أن يراها أي شخص آخر.
نصيحتي الأخيرة لك: لا تنتظر مكالمة غاضبة من عميلك أو مراجعة سلبية من مستخدميك. كن أنت الناقد الأقسى لواجهتك، ولكن دع الآلات تقوم بالعمل الشاق نيابة عنك. ابدأ اليوم، ولو بخطوة صغيرة، وسترى كيف ستنقذ نفسك وفريقك من جحيم كان من الممكن تجنبه.