TypeScript كل الأشياء في اختبارات Cypress الخاصة بك # frontend @ twiliosendgrid

نشرت: 2020-11-14

في Twilio SendGrid ، نكتب معظم تطبيقات الويب الأمامية ، خاصة الصفحات والميزات الجديدة ، باستخدام TypeScript و React اليوم من أجل فحص أفضل للنوع ، وقابلية الصيانة ، وتوثيق قاعدة الشفرات الخاصة بنا. عندما بدأنا في كتابة اختبارات Cypress منذ أكثر من عامين ، كان لا يزال يتم تنفيذ معظم كائنات الصفحة ، والمساعدات ، وملفات المواصفات في JavaScript وكنا في الغالب في Cypress الإصدار 3.xx تمت كتابة المزيد من الاختبارات الحديثة بالفعل في TypeScript لكننا لا يزال لديك عدد كبير من الملفات للتحويل والترحيل إلى TypeScript.

أردنا جني فوائد كتابة مكوناتنا واختبارات الوحدة واختبارات Cypress E2E بشكل كامل . ما جعل العملية أسهل هو الترحيل إلى إصدار أحدث من Cypress للاستفادة من دعم TypeScript خارج الصندوق منذ Cypress 4.4.0.

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

إذا كنت مستعدًا لمعرفة كيفية كتابة الأشياء ، فلنلقِ نظرة أولاً على بعض التغييرات الأولية مثل إضافة دعم TypeScript إلى Cypress إذا كنت قادمًا من إصدار أقدم.

الترحيل من Cypress 3.x إلى> = 4.4.0

بالنسبة لأولئك الذين قاموا بالفعل بتكوين البنية التحتية لـ Cypress الخاصة بهم للعمل مع TypeScript في إصدارات Cypress من 3.xx إلى 4.4.3 ، فمن المرجح أنك واجهت بعض التجارب والخطأ في إعداد التكوين المناسب لمعالج Webpack في plugins/index.js . بالنسبة لفريق Twilio SendGrid ، كان هناك بعض المشاكل مع بعض الملفات التي تحتاج إلى أن تكون ملفات JavaScript في plugins ومجلدات support وستظهر أخطاء Cypress التي يصعب تصحيحها. بمجرد أن تحصل على شيء يعمل ، يجب أن يبدو مثل هذا.


بعد الترقية من إصدار سابق من 3.xx ، تمكنا من إسقاط تكوين Webpack preprocessor الخاص بنا ، واستبدال ملف plugins/index.js بملف index.ts ، والعبث قليلاً بمجلد Cypress الخاص tsconfig.json ، وأخيراً ، باستخدام ملفات TS في مجلد Cypress الخاص بنا (مثل some_page.spec.ts أو index.d.ts أو page_object.ts ) - لم يعد هناك المزيد من تهيئة Webpack preprocessor وقد نجح الأمر للتو! لقد سررنا بمدى نظافة وأجمل عدم إدارة تكوين معالج Webpack الخاص بك والحصول على تغطية TypeScript أفضل لملفاتنا كما هو موضح أدناه.

مع تغطية دعم TypeScript ، نظرنا بعد ذلك إلى مثال تطبيق العالم الحقيقي لفريق Cypress ، وهو تطبيق cypress-real-world-app repo ، من أجل معرفة المزيد حول كيفية كتابة الأشياء بشكل أفضل. اكتشفنا كيفية كتابة cy.task(“pluginName”, { … }) و Cypress.env(“someEnvVar”) لاستدعاء تسلسل أفضل واكتب دعم intellisense عند تحديث الملفات. لقد بحثنا أيضًا في وثائق TypeScript المصاحبة. علمنا هذا كيفية كتابة أشياء مثل الأمر المخصص cy.login() بنا وكيفية إعداد ملف تكوين tsconfig.json . يحتوي التطبيق النموذجي أيضًا على tsconfig.json للرجوع إليه ، والذي يمكن أن يوفر لك تكوينًا أساسيًا رائعًا من TypeScript لتخصيصه وفقًا لتفضيلاتك. نوصيك بالبقاء على اطلاع دائم بأحدث إصدارات Cypress ، والغوص في موارد Cypress الرسمية ، وتجربة ملفات تعريف النوع.

كتابة أوامر مخصصة

أنشأنا بعض الأوامر المخصصة العالمية مثل cy.login() للتعامل مع تسجيل الدخول من خلال واجهة برمجة التطبيقات بحيث يمكن إعادة استخدامها في جميع ملفات المواصفات الخاصة بنا. فيما يلي مثال على كيفية كتابة أمر تسجيل الدخول المخصص الخاص بك مع إعطاء بيانات اعتماد المستخدم وإرجاع رمز المصادقة.

كتابة متغيرات البيئة

للتعامل مع بيئات اختبار متعددة مثل dev و staging ، استفدنا من تكوين متغيرات البيئة مثل: "testEnv" للاحتفاظ بالبيئة التي نختبرها حاليًا مثل التدريج ، و "apiHost" للاحتفاظ بمضيف واجهة برمجة التطبيقات الخلفية ، وغير ذلك المتغيرات. يمكنك كتابة Cypress.env() لكتابة الوظائف والكائنات الأخرى التي تعتمد على استخدام قيم متغيرات البيئة مثل هذه.

كتابة الإضافات

أنشأنا العديد من وظائف البرنامج المساعد cy.task() للتعامل مع الأشياء من استدعاءات واجهة برمجة التطبيقات ، والاستقصاء عن الخدمات ، والتحقق من مطابقة رسائل البريد الإلكتروني في صناديق البريد الإلكتروني التجريبية. في السابق عند تسلسل أي من استدعاءات الوظائف هذه مثل cy.task().then((data) => {}) ، كان موضوع البيانات المتسلسل يُكتب any أو unknown ، وهو ما لم يكن رائعًا لملفات TypeScript الخاصة بنا. اكتشفنا من خلال أمثلة Cypress كيفية كتابة المكونات الإضافية بشكل أفضل بناءً على اسم المكون الإضافي والوسيطات التي تم تمريرها في استدعاءات الوظيفة. سمح ذلك لملفات TypeScript الخاصة بنا باكتشاف نوع البيانات المتسلسلة.

إحدى المشكلات الدقيقة التي واجهناها هي أن اسم المكون الإضافي cy.task() يجب أن تتطابق تمامًا مع الطريقة التي كتبتها بها. وجدنا أنه من المهم التمرير فوق .then() تحقق من تطابق الأنواع بشكل صحيح. في بعض الأحيان ، إذا كنت تستخدم موضوعًا متسلسلًا من وظيفة Cypress أخرى مثل cy.getCookie(“auth_token”).its(“value”).then((token) => { }) أو cy.wrap(data).then((data) => {}) ، تحتاج إلى كتابة وسيطات البيانات المتسلسلة هذه أيضًا قبل تمريرها كوسيطة دالة cy.task(...).then((data) => { }) cy.task(..., { token, data }) وإلا ستظل ترى cy.task(...).then((data) => { }) جزء بيانات مكتوب على أنه any جزء أو unknown . من الأفضل لك أن تكون أكثر وضوحًا في الكثير من أنواع وظائف Cypress المتسلسلة مثل .its(“value”).then((token: string) => {}) أو cy.wrap(data).then((data: DataType) => {}) قبل تمريرها كجزء من كائن وسيطات cy.task() للتأكد من أن الأنواع تعمل مرة أخرى.

لقد أنشأنا ملفات منفصلة لأنواع المكون الإضافي والتي من شأنها تصدير الوظائف لاستخدامها مرة أخرى في plugins/index.ts . نظرًا لتزايد عدد المكونات الإضافية ، نوصيك بتنظيم عمليات تنفيذ وظائف المكونات الإضافية هذه حسب الصفحة أو الميزة للحفاظ على حجم ملف plugins/index.ts صغيرًا. يجب أن تسهل عليك القراءة بنظرة واحدة حيث تحدد جميع cy.task(...) في ملف plugins/index.ts . يمكنك أخيرًا كتابة وظائف المهام هذه في index.d.ts الخاص بك بالطريقة التالية:

وضع كل ذلك معًا في ملف إقرار النوع

وضعنا جميع أنواعنا لأوامرنا المخصصة ومتغيرات البيئة والمكونات الإضافية في ملف index.d.ts في مجلد support . نوصيك بوضع جميع أنواع Cypress الخاصة بك أيضًا في ملف تعريف TypeScript رئيسي للحفاظ على تنظيم الأشياء. لتجاوز الأنواع المفقودة في التبعيات الخارجية المستخدمة في كود اختبار Cypress الخاص بك ، يمكنك أيضًا تحديد ملفات الوحدة النمطية مثل “some-lib.d.ts” ، والتي قد تتضمن declare module 'some-lib' ، لحل تحذيرات TypeScript الخاصة بالمكتبة. يمكنك أيضًا استخدام ميزة أنواع الاستيراد في TypeScript لإحضار الأنواع / الواجهات المحددة داخل ملفات الإضافات / الأدوات الأخرى لتجنب تكرار تعريفات الأنواع في ملفات متعددة. يمكنك إضافة هذه الأنواع داخل مساحة اسم Cypress وتنظيمها بالطريقة التالية:

كتابة كائنات اختبار تركيبات وكائنات الصفحة وملفات المواصفات

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

تعتمد كتابة كائنات الصفحة وكتابة ملفات المواصفات المقابلة على أوامر Cypress والمكونات الإضافية والأدوات المساعدة الأخرى التي تستخدمها. بالنسبة للجزء الأكبر ، لا تتطلب كتابة كائنات الصفحة أو ملفات المواصفات العديد من التغييرات من نظرائهم في JavaScript (بافتراض أنك كتبت الإضافات واستدعاءات متغيرات البيئة بالفعل). في بعض الأحيان ، قد تحتاج وظيفة مساعد كائن الصفحة التي حددتها إلى كتابة بعض الوسائط أو قد يلزم كتابة الاستجابة القادمة من cy.request() as response.body as SomeType . بشكل عام ، يمكن للمحرر الخاص بك مثل VSCode أن يكتشف تلقائيًا الأنواع المتسلسلة من cy.task() أو cy.customCommand() دون الحاجة إلى إضافة المزيد من الأنواع في ملفات المواصفات الخاصة بك للتعويض عن أي تحذيرات من TypeScript.

فيما يلي مثال على أجزاء من كائن الصفحة مع بعض الوظائف المساعدة وملف المواصفات الذي يستخدم كائن الصفحة ، والأمر المخصص لتسجيل الدخول ، ومهام البرنامج المساعد.

خاتمة

ساعدتنا إضافة TypeScript إلى اختبارات Cypress لدينا على تجنب الأخطاء وتحسين تجربة المطور لدينا عند كتابة اختبارات Cypress. عند استخدام cy.task() و Cypress.env() و cy.customCommand() ، يمكننا الحصول على فحص أفضل للنوع على وسيطات ومخرجات الوظيفة وكذلك الاستفادة من إكمال الكود في IDE الخاص بنا مثل VSCode.

المفتاح هو إنشاء ملف تعريف النوع الخاص بك مثل ملف index.d.ts حيث يمكنك تجاوز أو تمديد واجهات "Cypress" و "Chainable" استنادًا إلى الأوامر المخصصة ومتغيرات البيئة ووظائف البرنامج المساعد للمهام. استخدام. في كائن صفحتك وملفات TypeScript المواصفات ، يمكنك بعد ذلك استخدام وظائف Cypress هذه وتحريك مؤشر الماوس فوق تعريف أنواع الإدخال والمخرجات المتوقعة أو اتباعها.

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

إذا كنت مهتمًا بمزيد من المنشورات المتعلقة بما تعلمناه من اختبارات Cypress ، فإليك بعض المقالات التي يجب عليك التحقق منها:

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