تسليم منتج مستقر باستخدام Cypress

Fei Han

February 7, 2021

Ecosystem

تم تصميم لوحة تحكم Apache APISIX لتسهيل عملية تشغيل Apache APISIX من خلال واجهة أمامية، ومنذ بداية المشروع، تم إجراء 552 عملية إيداع و10 إصدارات. مع مثل هذه التكرارات السريعة للمنتج، من المهم ضمان جودة المنتج مفتوح المصدر. لهذا السبب، قمنا بإدخال وحدة اختبار E2E لضمان تسليم منتج مستقر.

ما هو اختبار E2E الأمامي؟

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

لماذا Cypress

استخدمنا Taiko وPuppeteer وTestCafe وCypress لكتابة حالات اختبار لإنشاء طرق خلال فترة البحث والاختيار، واستخدمنا كل إطار اختبار لكتابة حالات لتجربة ميزاتها الخاصة.

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

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

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

بعد مقارنة شاملة، اخترنا أخيرًا Cypress كإطار عمل E2E الأمامي، مع ذكر أربعة أسباب رئيسية:

  1. بناء الجملة البسيط

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

  1. التصحيح السهل

عند تصحيح حالات الاختبار، يمكننا استخدام Test Runner الخاص بـ Cypress، الذي يعرض بيانات متعددة الأبعاد تسمح لنا بتحديد المشكلة بسرعة.

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

لدى Cypress مجتمع كبير من المستخدمين، وهناك دائمًا العديد من الأشخاص داخل المجتمع يشاركون تجاربهم وأفكارهم.

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

  1. وثائق واضحة

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

Cypress ولوحة تحكم APISIX

هناك حاليًا 49 حالة اختبار مكتوبة للوحة تحكم APISIX. قمنا بتكوين CI المقابل في GitHub Action لضمان مرور الكود قبل كل دمج لضمان جودة الكود. نشارك استخدام Cypress في لوحة تحكم APISIX معك من خلال الرجوع إلى أفضل ممارسات Cypress ودمجها مع مشروعنا.

صورة

  1. يتم تغليف الوظائف الشائعة كأوامر.

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

Cypress.Commands.add("login", () => {
  cy.request(
    "POST",
    'http://127.0.0.1/apisix/admin/user/login',
    {
      username: "user",
      password: "user",
    }
  ).then((res) => {
    expect(res.body.code).to.equal(0);
    localStorage.setItem("token", res.body.data.token);
  });
});
beforeEach(() => {
   // بدء تسجيل الدخول
   cy.login();
})
  1. استخراج المحدد والبيانات كمتغيرات عامة.

لجعل فهم معنى كود الاختبار أكثر وضوحًا للمستخدم، نقوم باستخراج selcector والبيانات كمتغيرات عامة.

  const data = {
    name: 'hmac-auth',
    deleteSuccess: 'تم حذف المكون الإضافي بنجاح',
  };
  const domSelector = {
    tableCell: '.ant-table-cell',
    empty: '.ant-empty-normal',
    refresh: '.anticon-reload',
    codemirror: '.CodeMirror',
    switch: '#disable',
    deleteBtn: '.ant-btn-dangerous',
  };
  1. إزالة cy.wait(someTime)

استخدمنا cy.wait(someTime) في الأيام الأولى من استخدام Cypress، ولكن وجدنا أن cy.wait(someTime) يعتمد بشكل كبير على بيئة الشبكة وأداء جهاز الاختبار، مما قد يتسبب في إبلاغ حالات الاختبار عن أخطاء عندما تكون بيئة الشبكة أو أداء الجهاز ضعيفًا. الممارسة الموصى بها هي استخدامها مع cy.intercept() لتحديد موارد الشبكة التي يجب انتظارها بشكل صريح.

cy.intercept("https://apisix.apache.org/").as("fetchURL");
cy.wait("@fetchURL");

الخلاصة

حاليًا، تم كتابة 49 حالة اختبار للوحة تحكم APISIX. في المستقبل، سنواصل تعزيز تغطية E2E الأمامية، ونطلب من المجتمع الموافقة على كتابة حالات اختبار لكل ميزة جديدة أو إصلاح خطأ يتم تقديمه لضمان استقرار المنتج.

مرحبًا بكم للانضمام إلينا لصقل منتج البوابة العالمي.

عنوان المشروع: https://github.com/apache/apisix-dashboard

Tags: