هذا المقال غير منشور بعد وغير مرئي لمحركات البحث.
الاختبار البصري في Monorepo: كيف لا تختبر 47 مشروعًا عند كل Commit

الاختبار البصري في Monorepo: كيف لا تختبر 47 مشروعًا عند كل Commit

المستودع الأحادي (monorepo) هو بنية معمارية لإدارة الكود المصدري حيث تتعايش مشاريع متعددة وتطبيقات مختلفة ومكتبات مشتركة في مستودع Git واحد، تُدار وتُنسّق بواسطة أدوات تنسيق متخصصة مثل Nx أو Turborepo أو Lerna التي تُحسّن عمليات البناء والاختبار بناءً على رسم بياني للتبعيات الدقيق والمفصّل.

لقد انتصرت بنية المستودعات الأحادية بالفعل. فرق الـ front-end التي تدير تطبيقات متعددة في وقت واحد — موقع تسويقي، لوحة تحكم إدارية، تطبيق عميل، بوابة شركاء — تجمعها جميعًا في مستودع واحد مركزي. إنه أبسط بكثير لمشاركة الكود بين الفرق، وأكثر اتساقًا لنظام التصميم الموحّد، وأكثر كفاءة بمراحل للتحديثات الشاملة والمتقاطعة.

لكن بالنسبة للاختبار البصري، إنه كابوس لوجستي حقيقي. ليس لأن الاختبار البصري لا يعمل في بيئة monorepo — فهو يعمل جيدًا تمامًا. المشكلة الحقيقية أنه يعمل بشكل جيد جدًا: أي تغيير ولو بسيط في حزمة مشتركة يُطلق محتملًا اختبارات بصرية على جميع المشاريع التي تعتمد عليه. وعندما يحتوي monorepo الخاص بك على 15 أو 30 أو 50 مشروعًا، فإن مقاربة "اختبار كل شيء عند كل commit" تصبح غير ممكنة عمليًا وغير قابلة للتطبيق.

المشكلة الأساسية: رسم بياني التبعيات

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

لنأخذ مثالًا ملموسًا وعمليًا. لديك حزمة "ui-components" تحتوي على الأزرار والنماذج ومكونات التنقل. هذه الحزمة تُستخدم من قبل 12 تطبيقًا مختلفًا في monorepo الخاص بك. أنت تُعدّل padding زر في حزمة "ui-components" — بصريًا، هذا التغيير يؤثر محتملًا على جميع التطبيقات الـ 12. كل صفحة تحتوي على زر قد تُعرض بشكل مختلف تمامًا.

إذا أطلقت اختبارات بصرية شاملة على التطبيقات الـ 12 كلها، فأنت تلتقط محتملًا مئات لقطات الشاشة. يستغرق pipeline الـ CI/CD حوالي 45 دقيقة كاملة. المطورون ينتظرون بصبر. وإذا فشل أحد الاختبارات — إيجابية كاذبة ناتجة عن مشكلة عرض headless — يجب على مطور حزمة "ui-components" أن يتحقيق في فشل حدث في تطبيق لا يعرفه حتى ولا يفهم هيكله.

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

اختبر ما تغيّر فقط، ليس كل شيء: مبدأ التأثر

القاعدة الأولى والأساسية للاختبار البصري في monorepo بسيطة نظريًا، لكنها معقدة عمليًا: اختبر فقط ما تأثر فعليًا بالتغيير الذي تم إجراؤه.

أدوات monorepo الحديثة — مع Nx و Turborepo في المقدمة والريادة — تعرف كيف تحسب رسم التبعيات البياني بدقة وتحدد المشاريع "المتأثرة" بالتغيير. عندما تُعدّل ملفًا في حزمة "ui-components"، يمكن لـ Nx أن يخبرك بوضوح أن التطبيقات A و C و F و K تعتمد على هذه الحزمة، لكن ليس B و D والبقية.

هذه هي الأساس المتين. لكن للاختبار البصري، هذا غير كافٍ إطلاقًا. لأن "التطبيق A يعتمد على حزمة ui-components" لا يعني أن جميع صفحات التطبيق A تستخدم المكون المُعدّل فعليًا. إذا غيّرت الزر، فقط الصفحات التي تحتوي على زر هي المتأثرة حقيقةً. الصفحات بدون زر تبقى مستقرة وغير متأثرة.

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

المستوى الأول تحلّه أدوات monorepo بسهولة. المستوى الثاني أصعب بكثير بكثير — يتطلب إما تحليلًا ثابتًا للكود المصدري (أي صفحات تستورد أي مكون محدد) أو تعيينًا صريحًا تحافظ عليه الفرقة وتُحدّثه باستمرار (هذا المكون يُستخدم في هذه الصفحات بالتحديد).

واقع الحزم المشتركة وتأثيرها

الحزم المشتركة تمثل في آن واحد قوة وضعف بنية monorepo. تُتيح الاتساق البصري والوظيفي: نظام تصميم واحد وموحد، مصدر حقيقة واحد للمكونات البصرية. لكنها تُنشئ أيضًا نطاق انفجار كبير ومخيف عند حدوث أي تغيير.

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

حزم مكونات واجهة المستخدم (UI). هذه هي الحالة الأوضح والأكثر مباشرة. تغيير في زر أو نموذج أو نافذة حوارية يؤثر بصريًا وبشكل مباشر على جميع الصفحات التي تستخدمها. نطاق الانفجار يتناسب طرديًا مع شعبية المكون. مكون تخطيط (layout) يُستخدم في كل مكان (Header، Footer، Sidebar) له نطاق انفجار أقصى ممكن.

حزم الأنماط والرموز التصميمية (tokens). تغيير في design tokens — الألوان والمسافات والخطوط — غالبًا ما يكون غير مرئي في رسم التبعيات التقليدي. إذا عدّلت اللون الأساسي في ملف الرموز، يرى رسم التبعيات تغييرًا في حزمة "design-tokens" فقط. لكن هذا التغيير يؤثر بصريًا على كل شيء تقريبًا: كل زر أساسي، كل رابط، كل عنصر مُميّز في جميع التطبيقات دون استثناء. نطاق الانفجار هنا كامل وشامل.

حزم الأدوات المساعدة ذات التأثيرات البصرية الجانبية. هذا النوع أقل وضوحًا: الدوال المساعدة التي تُنسّق التواريخ أو تقطع النصوص أو تحسب التخطيطات. تغيير في دالة قطع النص — من 100 إلى 80 حرفًا كحد أقصى — له تأثير بصري مباشر وملموس على جميع المكونات التي تستخدمها. لكن رسم التبعيات لا يعرف ولا يستطيع أن يدرك أنه تغيير "بصري" بامتياز.

الاستراتيجيات المُثبتة التي تعمل فعليًا

بعد مراقبة عشرات الفرق المختلفة وهي تدير الاختبار البصري في بيئات monorepo، إليك الاستراتيجيات التي أثبتت أنها تُنتج أفضل النتائج بشكل متكرر ومتسق.

الاستراتيجية 1: الاختبار البصري بالطبقات المتدرجة

نظّم اختباراتك البصرية في ثلاث طبقات واضحة بترددات تنفيذ مختلفة ومحددة لكل طبقة.

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

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

الطبقة الكاملة الشاملة. اختبر جميع صفحات جميع التطبيقات دون استثناء. هذه الطبقة لا تُنفّذ على كل PR — فهي مكلفة جدًا من حيث الوقت والموارد. نفّذها مرة واحدة يوميًا (nightly) أو قبل كل إصدار جديد. تلتقط التراجعات التي لم يستطع رسم التبعيات التنبؤ بها مسبقًا.

الاستراتيجية 2: تعيين صريح من المكون إلى الصفحة

حافظ على ملف تكوين دقيق يربط كل مكون مشترك بالصفحات التي تستخدمه فعليًا. عندما يتغير مكون Button مثلًا، يُشير الملف بوضوح إلى أن صفحات /login و /signup و /checkout و /settings في التطبيق A تستخدم هذا المكون. فقط هذه الصفحات المحددة تُختبر ولا شيء غيرها.

هذا التعيين مُملّ ومتعب للحفاظ عليه يدويًا. لكن يمكن توليده تلقائيًا بالكامل من خلال تحليل ثابت للكود المصدري — بالمرور على جميع واردات كل صفحة وتتبع سلسلة التبعيات. يقدم Nx إضافات متخصصة تُسهّل وتُسرّع هذا النوع من التحليل البرمجي.

الميزة والفائدة كبيرة جدًا: بدلًا من اختبار 200 صفحة من التطبيق A عند تغيير مكون واحد، تختبر 12 صفحة فقط. ينخفض وقت pipeline من 30 دقيقة إلى 3 دقائق فقط.

الاستراتيجية 3: baseline مشترك مع آلية التجاوز

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

عمليًا: عندما تُعدّل مكون Button، تحدّث baseline الـ Button في حزمة ui-components. التطبيقات التي تستخدم Button ترث تلقائيًا هذا baseline الجديد. فقط التطبيقات حيث يُعرض Button بشكل مختلف في السياق (بسبب CSS خاص أو سمة (theme) مختلفة أو تجاوز يدوي) تحتاج إلى امتلاك baselines خاصة بها.

الأخطاء الكلاسيكية التي يجب تجنبها تمامًا

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

تجاهل رسم التبعيات البياني. بعض الفرق تُهيّئ اختباراتها البصرية بشكل مستقل تمامًا عن أداة monorepo. النتيجة المتوقعة: الاختبارات لا تعرف أي المشاريع متأثرة فعلًا وتختبر إما كل شيء أو لا شيء. ادمج أداة الاختبار البصري مع Nx أو Turborepo واستخدم أوامرهم "affected" لإطلاق الاختبارات الصحيحة فقط.

وضع جميع الـ baselines في مجلد واحد مركزي. يجب أن تعيش الـ baselines البصرية بجانب المشاريع التي تحميها وتخدمها. إذا جمعت كل baselines في مجلد جذر واحد، تفقد الدقة والتحكم: لم تعد تعرف أي baseline ينتمي لأي مشروع، وتنظيف baselines المتقادمة والقديمة يصبح مستحيلًا عمليًا.

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

دور CI/CD في الاختبار البصري لـ monorepo

تهيئة CI/CD السليمة أمر حاسم وجوهري. يجب أن يكون pipeline الخاص بك قادرًا على ثلاثة أشياء أساسية.

أولًا، حساب مجموعة المشاريع المتأثرة بالتغيير بدقة. هذا هو عمل Nx (nx affected) أو Turborepo (turbo run --filter). هذه الخطوة تحدد وتُحدد نطاق الاختبارات المطلوبة.

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

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

عندما يُبسّط الـ no-code كل شيء

أدوات الاختبار البصري القائمة على الكود — مثل Playwright، و Cypress مع إضافات بصرية — تندمج جيدًا في بنية monorepo لأنها تعيش في نفس المستودع بجانب الكود الذي تختبره. لكنها تُضيف كود اختبار إضافي للصيانة، وتكوينات منفصلة لكل مشروع، وسكربتات CI/CD خاصة ومخصصة.

الأدوات بدون كود مثل Delta-QA تقترح نهجًا مختلفًا تمامًا. بدلًا من الاختبار من الكود المصدري مباشرة، تختبر من URLs المنشورة فعليًا. تُهيّئ URLs كل تطبيق، تلتقط الأداة لقطات الشاشة وتقارنها تلقائيًا بالـ baselines المرجعية. لم يعد monorepo عامل تعقيد — الأداة ترى فقط URLs بسيطة، وليس حزمًا معقدة.

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

الأسئلة الشائعة

هل Nx أو Turborepo أفضل للاختبار البصري في monorepo؟

Nx لديه ميزة واضحة وكبيرة بفضل رسم التبعيات الأكثر تفصيلًا ودقة وإضافات التحليل الثابت المتقدمة. أمر nx affected يحدد بدقة تامة المشاريع المتأثرة، ومنفذو Nx يسمحون بدمج مهام الاختبار البصري في رسم المهام العام بسلاسة. Turborepo أبسط في الاستخدام لكنه يقدم ترشيحًا أقل دقة وشمولية.

كيف تدير baselines عندما يتغير design token ويؤثر على كل شيء؟

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

كم من الوقت يجب أن يستغرق اختبار بصري في pipeline monorepo؟

باستهداف المشاريع المتأثرة فقط: أقل من 10 دقائق لـ PR قياسية تمس مشروعًا واحدًا. أقل من 20 دقيقة لتغيير في حزمة مشتركة يؤثر على 3 إلى 5 مشاريع. إذا استغرقت اختباراتك أكثر من 30 دقيقة على أي PR، فإن استراتيجية الترشيح لديك غير كافية وتحتاج إلى مراجعة. الطبقة الكاملة (nightly) يمكن أن تستغرق وقتًا أطول — 30 إلى 60 دقيقة يُعدّ أمرًا مقبولًا.

هل يجب أن تكون هناك baselines منفصلة لكل بيئة (dev، staging، prod)؟

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

هل يعمل الاختبار البصري في monorepo مع Lerna؟

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

كيف تمنع المطورين من تجاهل نتائج الاختبار البصري؟

ثلاث قواعد ذهبية. حافظ على معدل الإيجابيات الكاذبة قريبًا جدًا من الصفر — إذا رأى المطورون إيجابيات كاذبة بشكل متكرر، سيتوقفون عن النظر في النتائج. احظر دمج PRs عند فشل أي اختبار بصري — لا merge دون موافقة صريحة. واحرص على أن تكون أوقات pipeline قصيرة — إذا أضاف الاختبار البصري 45 دقيقة لكل PR، سيجد المطورون طرقًا ملتوية لتجاوزه وتعطيله.


للمزيد من القراءة


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

جرّب Delta-QA مجانًا →