دمج اختبارات السرو مع Docker و Buildkite و CICD # frontend @ twiliosendgrid

نشرت: 2020-12-30

لقد كتبنا الكثير من اختبارات Cypress (E2E) للتحقق من صحة تطبيقات الويب الخاصة بنا والتي لا تزال تعمل كما هو متوقع مع الواجهة الخلفية. بعد كتابة اختبارات التشغيل الآلي للمتصفح ، نود دائمًا تشغيل اختبارات Cypress هذه أو تشغيلها بطريقة ما مثل اختبارات الوحدة الخاصة بنا قبل دمج الكود ونشره في بيئات معينة. قادنا ذلك إلى مسار الرغبة في إجراء اختبارات Cypress الخاصة بنا في حاوية Docker للتكامل مع مزود التكامل المستمر (CI) والآلات التي نستخدمها في السحابة لتشغيل هذه الحاويات.

عندما يتعلق الأمر بتدفقات النشر ، فإننا نستخدم Buildkite كمزود CI الخاص بنا. يتيح لنا ذلك إنشاء مجموعة من الخطوات الآلية لتطبيقنا في خط أنابيب Buildkite عندما نخطط لنقل الكود عبر اللوحة. لمزيد من السياق ، يكون خط الأنابيب مكانًا مرتبطًا عادةً بمستودع التطبيق حيث يمكننا النظر في البنيات أو تشغيل البنيات بخطوات معينة للتشغيل عند إنشاء طلبات السحب ، ودفع تغييرات التعليمات البرمجية الجديدة ، ودمج التعليمات البرمجية لإتقانها ، والنشر في بيئات مختلفة . نقوم بإنشاء خطوط أنابيب متعددة لأغراض منفصلة مثل النشر واختبارات Cypress التي تم تشغيلها واختبارات Cypress المحددة التي تعمل وفقًا لجدول زمني.

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

نهدف إلى إرشادك إلى أفكار حول كيفية دمج اختبارات Cypress في حاوية Docker مع موفر CI الخاص بك من خلال إلقاء نظرة على كيفية قيامنا بذلك باستخدام Docker Compose و Buildkite في خط أنابيب النشر الخاص بنا. يمكن توسيع هذه الأفكار في البنية التحتية الخاصة بك للاستراتيجيات والأوامر ومتغيرات البيئة لتطبيقها عند تشغيل اختبارات Cypress.

تدفق CICD القياسي لدينا

في تدفق التطوير والنشر القياسي لدينا ، قمنا بإنشاء خطين للأنابيب:

  1. الأول يتعامل مع خطوات النشر الخاصة بنا عندما ندفع الكود.
  2. الثاني يؤدي إلى تشغيل اختبارات السرو بالتوازي وتسجيلها. يؤثر نجاح أو فشل هذا على خط أنابيب النشر.

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

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

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

بعد ذلك ، قمنا بتنفيذ سكربت Bash الخاص بنا المسمى runCypress.sh ليتم تشغيله بعد تلك الخطوة المحددة لتحليل قيم "نعم" أو "لا" المحددة. نقوم بذلك لتشكيل قائمة بمسارات المواصفات المفصولة بفواصل لتشغيلها وإلحاقها كخيار ، --spec ، بأمر Cypress النهائي الذي يعمل في حاوية Docker في خط أنابيب مُشغل. نقوم بتصدير متغيرات البيئة مثل قائمة المواصفات المكونة في "CYPRESS_SPECS" وبيئة الاختبار الحالية في "CYPRESS_TEST_ENV" لاستخدامها في خط الأنابيب الذي نقوم بتشغيله في نهاية البرنامج النصي مع buildkite-agent pipeline upload "$DIRNAME"/triggerCypress.yml .

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

إذا قمنا بتعيين "ASYNC" على "خطأ" ، فسيتم حظر خطوات خط أنابيب النشر الرئيسية لدينا حتى تنتهي اختبارات Cypress التي تم تشغيلها في خط أنابيب مختلف. يؤدي نجاح أو فشل الإنشاء المشغل إلى النجاح أو الفشل الكلي لخط أنابيب النشر حيث يبدأ بعد ذلك.

عندما لا يزال الكود الخاص بنا في فرع ميزة مع طلب سحب مفتوح ، نود دفع المزيد من التغييرات ، وتشغيل بعض اختبارات Cypress ، ونرى كيف تتصرف الأشياء. لكننا لا نريد دائمًا منع بقية خطوات خط أنابيب النشر من العمل إذا فشلت الاختبارات التي تم تشغيلها نظرًا لوجود المزيد من التغييرات على طول الطريق. في هذا السيناريو ، قمنا بتعيين "ASYNC" على خطأ لعدم حظره إذا فشلت اختبارات Cypress. بالنسبة للحالة التي قمنا فيها بالفعل بدمج طلب السحب الخاص بنا في النظام الرئيسي ونشرنا على التدريج ولكننا نريد تشغيل اختبارات Cypress قبل أن ننتشر في الإنتاج ، فقد قمنا بتعيين "ASYNC" على true لأننا نريد أن تمر اختبارات Cypress دائمًا قبل الخروج إلى الإنتاج .

بالعودة إلى runCypress.sh ، نتذكر أن البرنامج النصي يقوم بتشغيل خط الأنابيب الثاني للتشغيل عن طريق استدعاء ملف triggerCypress.yml مع قيم متغير البيئة المعينة. يبدو ملف triggerCypress.yml مثل هذا. ستلاحظ أن خطوة "المشغل" واستيفاء القيم في رسائل الإنشاء مفيدة لتصحيح الأخطاء وأسماء الخطوات الديناميكية.

سواء قمنا بتشغيل اختبارات Cypress للتشغيل من خط أنابيب النشر الخاص بنا إلى خط أنابيب تشغيل منفصل أو إجراء اختبارات Cypress وفقًا لجدول زمني في خط أنابيب مخصص ، فإننا نتبع نفس الخطوات ونعيد استخدامها مع تغيير قيم متغيرات البيئة فقط.

تتضمن هذه الخطوات:

  1. بناء صورة Docker بأحدث علامة وعلامة إصدار فريدة
  2. دفع صورة Docker إلى سجلنا الخاص
  3. سحب نفس الصورة لأسفل لإجراء اختبارات Cypress الخاصة بنا بناءً على قيم متغير البيئة الخاصة بنا في حاوية Docker

هذه الخطوات موضحة في ملف pipeline.cypress.yml مثل:

عندما نشغل اختبارات Cypress للتشغيل ، فإنها ستبدأ بناء منفصل في خط أنابيب تشغيل Cypress. بناءً على نجاح أو فشل الإنشاء ، فإن تشغيل اختبار Cypress إما سيمنعنا أو يسمح لنا بالنشر في الإنتاج عندما ننتقل من مرحلة الإنتاج إلى مرحلة الإنتاج لبنيات الفروع الرئيسية.

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

إذا كنت مهتمًا بكيفية اتصال جزء Docker بالكامل ، فإن Dockerfile.cypress و package.json docker-compose.cypress.yml compose.cypress.yml يستخدمان متغيرات البيئة التي تم تصديرها من خطوط الأنابيب الخاصة بنا لاستخدام أمر Cypress المناسب من حزمة تطبيقنا. بيئة الاختبار وتشغيل ملفات المواصفات المحددة. توضح المقتطفات أدناه نهجنا العام الذي يمكنك التوسع فيه وتحسينه لتكون أكثر مرونة.


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

التوازي

نستخدم أيضًا علامة الموازاة للاستفادة من عدد آلات AWS التي يمكننا تدويرها من قائمة انتظار وكلاء الإنشاء التي أنشأها فريق العمليات لدينا. باستخدام علم الموازاة هذا ، يُظهر Cypress تلقائيًا عددًا معينًا من الآلات بناءً على الرقم الذي حددناه في خاصية Buildkite "المتوازية".

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

ثم ينتشر بعد ذلك جميع اختبارات Cypress للتشغيل بالتوازي عبر تلك الأجهزة مع الحفاظ على تسجيل كل اختبار من الاختبارات لتشغيل بناء معين. عزز هذا أوقات تشغيل الاختبار لدينا بشكل كبير!

فيما يلي بعض النصائح عند إجراء موازاة اختبارات السرو:

  • اتبع الاقتراحات الواردة في Dashboard Service للحصول على العدد الأمثل من الآلات وتعيين عدد الأجهزة في متغير البيئة لتحقيق المرونة في خطوط الأنابيب الخاصة بك.
  • قم بتقسيمها إلى ملفات اختبار أصغر ، خاصةً تقسيم الاختبارات التي تعمل لفترة أطول إلى أجزاء يمكننا موازنتها بشكل أفضل عبر الأجهزة.
  • تأكد من أن اختبارات السرو الخاصة بك معزولة ولا تؤثر على بعضها البعض أو تعتمد على بعضها البعض. عند التعامل مع التدفقات ذات الصلة بالتحديث أو الإنشاء أو الحذف ، استخدم مستخدمين منفصلين وموارد البيانات لتجنب الاختبارات التي تدوس على بعضها البعض وتواجه ظروف السباق. يمكن تشغيل ملفات الاختبار الخاصة بك بأي ترتيب ، لذا تأكد من أن هذه ليست مشكلة عند تشغيل جميع اختباراتك.
  • بالنسبة إلى Buildkite ، تذكر أن تمرر القيمة المتغيرة لبيئة Buildkite build ID إلى الخيار --ci-build-id بالإضافة إلى الخيار parallel حتى يعرف أي تشغيل بناء فريد يرتبط به عند إجراء اختبارات متوازية عبر الأجهزة.

للمراجعة:

من أجل ربط اختبارات Cypress بمزود CI الخاص بك مثل Buildkite ، سوف تحتاج إلى:

  1. قم ببناء صورة Docker مع كود التطبيق الخاص بك ، باستخدام الصورة الأساسية Cypress الضرورية والتبعيات المطلوبة لتشغيل الاختبارات في بيئة Node ضد متصفحات معينة.
  2. ادفع صورة Docker الخاصة بك إلى سجل بعلامات معينة
  3. اسحب نفس الصورة لأسفل في خطوة لاحقة
  4. قم بتشغيل اختبارات Cypress في وضع مقطوعة الرأس وباستخدام مفاتيح التسجيل إذا كنت تستخدم Cypress Dashboard Service.
  5. قم بتعيين قيم متغيرات بيئة مختلفة وقم بتوصيلها بالأوامر التي تقوم بتشغيلها لـ Cypress لتشغيل اختبارات Cypress المحددة مقابل بيئة اختبار معينة في حاويات Docker هذه.

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

قم بإعداد أوامرك لتكون مرنة وقابلة للتكوين بناءً على قيم متغيرات البيئة.

بمجرد إجراء اختباراتك في Docker مع موفر CI الخاص بك (وإذا كنت تدفع مقابل خدمة Dashboard Service) ، يمكنك الاستفادة من موازاة اختباراتك عبر أجهزة متعددة. قد تضطر إلى تعديل الاختبارات والموارد الحالية بحيث لا تعتمد على أخرى لتجنب أي اختبارات تعثر على بعضها البعض.

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

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

تؤدي المحافظة على اجتياز الاختبارات ومراقبة عمليات الاختبار الفاشلة بجد في بيئات الاختبار لدينا إلى تقليل تذاكر الدعم والعملاء الأكثر سعادة في الإنتاج. يوفر الحفاظ على مجموعة صحية ومستقرة من اختبارات Cypress قيد التشغيل عند دفع تغييرات كود جديدة ثقة أكبر في أن الأمور تعمل بشكل جيد ونوصي بأن تفعل أنت وفرقك نفس الشيء مع اختبارات Cypress الخاصة بك.

لمزيد من الموارد حول اختبارات Cypress ، راجع المقالات التالية:

  • ما يجب مراعاته عند كتابة اختبارات E2E
  • نظرة عامة على 1000 قدم لكتابة اختبارات السرو
  • TypeScript كل الأشياء في اختبارات السرو الخاصة بك
  • التعامل مع تدفقات البريد الإلكتروني في اختبارات السرو
  • أفكار لتكوين وتنظيم وتوحيد اختبارات السرو الخاصة بك