دليل شامل لـ Cypress، إطار عمل الاختبارات الشاملة القوي، يغطي التثبيت وكتابة الاختبارات والتصحيح وتكامل CI/CD وأفضل الممارسات.
Cypress: الدليل الشامل للاختبارات الشاملة لتطبيقات الويب
في مشهد تطوير الويب الذي يتطور بسرعة اليوم، يعد ضمان جودة وموثوقية تطبيقات الويب أمرًا بالغ الأهمية. يلعب اختبار End-to-End (E2E) دورًا حاسمًا في التحقق من أن جميع مكونات التطبيق تعمل معًا بسلاسة من وجهة نظر المستخدم. برز Cypress كإطار عمل رائد لاختبار E2E، حيث يوفر تجربة سهلة الاستخدام للمطورين، وميزات قوية، وأداءً ممتازًا. سيرشدك هذا الدليل الشامل خلال كل ما تحتاج إلى معرفته للبدء باستخدام Cypress واختبار تطبيقات الويب الخاصة بك بفعالية.
ما هو Cypress؟
Cypress هو أداة اختبار من الجيل التالي للواجهة الأمامية تم إنشاؤها للويب الحديث. على عكس أطر عمل الاختبار التقليدية التي تقوم بتشغيل الاختبارات في متصفح، يعمل Cypress مباشرة في المتصفح، مما يمنحك تحكمًا ورؤية لا مثيل لهما في سلوك تطبيقك. إنه مصمم ليكون سريعًا وموثوقًا وسهل الاستخدام، مما يجعله خيارًا شائعًا بين المطورين ومهندسي ضمان الجودة في جميع أنحاء العالم. تم كتابة Cypress بلغة JavaScript ويتم تنفيذه داخل المتصفح، مما يجعله فعالاً للغاية ويوفر وصولاً منقطع النظير إلى التفاصيل الداخلية للتطبيق.
المزايا الرئيسية لاستخدام Cypress
- صديق للمطورين: يوفر Cypress واجهة برمجة تطبيقات نظيفة وبديهية، مما يجعل من السهل كتابة الاختبارات وتصحيحها.
- Time Travel: يلتقط Cypress لقطات لحالة تطبيقك أثناء كل أمر اختبار، مما يسمح لك بالعودة بالزمن ورؤية ما حدث بالضبط في أي وقت.
- إعادة تحميل في الوقت الفعلي: يعيد Cypress التحميل تلقائيًا عند إجراء تغييرات على الاختبارات الخاصة بك، مما يوفر ملاحظات فورية.
- الانتظار التلقائي: ينتظر Cypress تلقائيًا حتى تصبح العناصر مرئية أو قابلة للتفاعل قبل تنفيذ الإجراءات، مما يلغي الحاجة إلى الانتظارات الصريحة.
- التحكم في الشبكة: يسمح لك Cypress بتعيين طلبات واستجابات الشبكة، مما يتيح لك محاكاة سيناريوهات مختلفة واختبار معالجة الأخطاء في تطبيقك.
- إمكانية التصحيح: يوفر Cypress أدوات تصحيح ممتازة، بما في ذلك أداة تصحيح قوية ورسائل خطأ تفصيلية.
- الاختبار عبر المتصفحات: يدعم Cypress متصفحات متعددة، بما في ذلك Chrome و Firefox و Edge و Electron.
- الاختبار بدون رأس: قم بتشغيل الاختبارات في الوضع بدون رأس لتنفيذ أسرع في بيئات CI/CD.
- الادعاءات المضمنة: يوفر Cypress مجموعة غنية من الادعاءات المضمنة للتحقق من السلوك المتوقع لتطبيقك.
التثبيت والإعداد
البدء باستخدام Cypress أمر سهل. إليك كيفية تثبيته:
- المتطلبات الأساسية: تأكد من تثبيت Node.js و npm (Node Package Manager) على نظامك. يمكنك تنزيلها من موقع Node.js الرسمي.
- تثبيت Cypress: افتح المحطة الطرفية أو موجه الأوامر، وانتقل إلى دليل المشروع الخاص بك، وقم بتشغيل الأمر التالي:
- فتح Cypress: بمجرد اكتمال التثبيت، يمكنك فتح Cypress Test Runner عن طريق التشغيل:
npm install cypress --save-dev
npx cypress open
سيؤدي هذا الأمر إلى تشغيل Cypress Test Runner، والذي يوفر واجهة رسومية لتشغيل الاختبارات وتصحيحها.
كتابة أول اختبار Cypress لك
لنقم بإنشاء اختبار بسيط للتحقق من تحميل الصفحة الرئيسية لموقع ويب بشكل صحيح. قم بإنشاء ملف جديد باسم `example.cy.js` في الدليل `cypress/e2e` الخاص بمشروعك.
// cypress/e2e/example.cy.js
describe('اختباري الأول', () => {
it('يزور Kitchen Sink', () => {
cy.visit('https://example.cypress.io')
cy.contains('type').click()
cy.url().should('include', '/commands/actions')
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
})
})
دعنا نحلل هذا الاختبار:
- `describe()`: يحدد مجموعة اختبار، وهي مجموعة من الاختبارات ذات الصلة.
- `it()`: يحدد حالة اختبار فردية داخل مجموعة الاختبار.
- `cy.visit()`: ينتقل إلى عنوان URL المحدد.
- `cy.contains()`: يعثر على عنصر يحتوي على النص المحدد.
- `.click()`: ينقر على العنصر المحدد.
- `cy.url()`: يحصل على عنوان URL الحالي للصفحة.
- `.should()`: يقوم بتأكيد حول حالة التطبيق.
- `cy.get()`: يحدد عنصرًا باستخدام محدد CSS.
- `.type()`: يكتب نصًا في العنصر المحدد.
- `.should('have.value', 'fake@email.com')`: يؤكد أن قيمة العنصر تساوي 'fake@email.com'.
قم بتشغيل هذا الاختبار في Cypress Test Runner لرؤيته قيد التشغيل. يجب أن ترى المتصفح ينتقل إلى موقع Cypress Kitchen Sink على الويب، وينقر على رابط "type"، ويتحقق من عنوان URL.
أوامر Cypress
يوفر Cypress مجموعة واسعة من الأوامر للتفاعل مع تطبيقك. فيما يلي بعض الأوامر الأكثر استخدامًا:
- `cy.visit(url)`: ينتقل إلى عنوان URL المحدد.
- `cy.get(selector)`: يحدد عنصرًا باستخدام محدد CSS.
- `cy.contains(content)`: يحدد عنصرًا يحتوي على النص المحدد.
- `cy.click()`: ينقر على العنصر المحدد.
- `cy.type(text)`: يكتب نصًا في العنصر المحدد.
- `cy.clear()`: يمسح محتويات عنصر الإدخال أو textarea.
- `cy.submit()`: يرسل نموذجًا.
- `cy.check()`: يحدد خانة اختيار أو زر اختيار.
- `cy.uncheck()`: يزيل تحديد خانة اختيار.
- `cy.select(value)`: يحدد خيارًا من قائمة منسدلة.
- `cy.scrollTo(position)`: يقوم بتمرير الصفحة إلى الموضع المحدد.
- `cy.trigger(event)`: يؤدي إلى حدوث حدث DOM على العنصر المحدد.
- `cy.request(url, options)`: يقوم بإجراء طلب HTTP إلى عنوان URL المحدد.
- `cy.intercept(route, handler)`: يعترض طلبات HTTP التي تطابق المسار المحدد.
- `cy.wait(time)`: ينتظر للمدة الزمنية المحددة.
- `cy.reload()`: يعيد تحميل الصفحة الحالية.
- `cy.go(direction)`: ينتقل إلى الصفحة السابقة أو التالية في محفوظات المتصفح.
- `cy.url()`: يحصل على عنوان URL الحالي للصفحة.
- `cy.title()`: يحصل على عنوان الصفحة.
- `cy.window()`: يحصل على كائن النافذة.
- `cy.document()`: يحصل على كائن المستند.
- `cy.viewport(width, height)`: يحدد حجم منفذ العرض.
هذه مجرد أمثلة قليلة من الأوامر العديدة المتوفرة في Cypress. راجع وثائق Cypress للحصول على قائمة كاملة بالأوامر وخياراتها.
الادعاءات في Cypress
تُستخدم الادعاءات للتحقق من السلوك المتوقع لتطبيقك. يوفر Cypress مجموعة غنية من الادعاءات المضمنة التي يمكنك استخدامها للتحقق من حالة العناصر وعنوان URL والعنوان والمزيد. يتم ربط الادعاءات بعد أوامر Cypress باستخدام طريقة `.should()`.
فيما يلي بعض الأمثلة الشائعة للادعاءات:
- `.should('be.visible')`: يؤكد أن العنصر مرئي.
- `.should('not.be.visible')`: يؤكد أن العنصر غير مرئي.
- `.should('be.enabled')`: يؤكد أن العنصر ممكن.
- `.should('be.disabled')`: يؤكد أن العنصر معطل.
- `.should('have.text', 'expected text')`: يؤكد أن العنصر يحتوي على النص المحدد.
- `.should('contain', 'expected text')`: يؤكد أن العنصر يحتوي على النص المحدد.
- `.should('have.value', 'expected value')`: يؤكد أن العنصر يحتوي على القيمة المحددة.
- `.should('have.class', 'expected class')`: يؤكد أن العنصر يحتوي على الفئة المحددة.
- `.should('have.attr', 'attribute name', 'expected value')`: يؤكد أن العنصر يحتوي على السمة والقيمة المحددة.
- `.should('have.css', 'css property', 'expected value')`: يؤكد أن العنصر يحتوي على خاصية CSS والقيمة المحددة.
- `.should('have.length', expected length)`: يؤكد أن العنصر يحتوي على الطول المحدد (على سبيل المثال، عدد العناصر في قائمة).
يمكنك أيضًا إنشاء ادعاءات مخصصة لتناسب احتياجاتك الخاصة.
أفضل الممارسات لكتابة اختبارات Cypress
يمكن أن يساعدك اتباع أفضل الممارسات في كتابة اختبارات Cypress أكثر قابلية للصيانة وموثوقية وكفاءة. فيما يلي بعض التوصيات:
- اكتب اختبارات واضحة وموجزة: يجب أن يركز كل اختبار على وظيفة أو سيناريو معين. تجنب كتابة اختبارات معقدة للغاية يصعب فهمها وصيانتها.
- استخدم أسماء اختبارات ذات مغزى: امنح الاختبارات الخاصة بك أسماء وصفية تشير بوضوح إلى ما تختبره.
- تجنب القيم الثابتة: استخدم متغيرات أو ملفات تكوين لتخزين القيم التي قد تتغير بمرور الوقت.
- استخدم الأوامر المخصصة: قم بإنشاء أوامر مخصصة لتغليف المنطق القابل لإعادة الاستخدام وجعل الاختبارات الخاصة بك أكثر قابلية للقراءة.
- عزل الاختبارات: يجب أن يكون كل اختبار مستقلًا عن الاختبارات الأخرى. تجنب الاعتماد على حالة التطبيق من الاختبارات السابقة.
- التنظيف بعد الاختبارات: أعد تعيين حالة التطبيق بعد كل اختبار للتأكد من أن الاختبارات اللاحقة تبدأ من صفحة نظيفة.
- استخدم سمات البيانات: استخدم سمات البيانات (على سبيل المثال، `data-testid`) لتحديد العناصر في الاختبارات الخاصة بك. من غير المرجح أن تتغير سمات البيانات عن فئات أو معرفات CSS، مما يجعل الاختبارات الخاصة بك أكثر مرونة للتغييرات في واجهة المستخدم.
- تجنب الانتظارات الصريحة: ينتظر Cypress تلقائيًا حتى تصبح العناصر مرئية أو قابلة للتفاعل. تجنب استخدام الانتظارات الصريحة (على سبيل المثال، `cy.wait()`) إلا عند الضرورة القصوى.
- اختبار تدفقات المستخدم: ركز على اختبار تدفقات المستخدم بدلاً من المكونات الفردية. سيساعدك هذا على التأكد من أن تطبيقك يعمل بشكل صحيح من وجهة نظر المستخدم.
- تشغيل الاختبارات بانتظام: قم بدمج اختبارات Cypress في خط أنابيب CI/CD وقم بتشغيلها بانتظام لاكتشاف الأخطاء في وقت مبكر من عملية التطوير.
تقنيات Cypress المتقدمة
Stubbing and Mocking
يسمح لك Cypress بتعيين طلبات واستجابات الشبكة، مما يتيح لك محاكاة سيناريوهات مختلفة واختبار معالجة الأخطاء في تطبيقك. هذا مفيد بشكل خاص لاختبار الميزات التي تعتمد على واجهات برمجة التطبيقات أو الخدمات الخارجية.
لتعيين طلب شبكة، يمكنك استخدام الأمر `cy.intercept()`. على سبيل المثال، يقوم الكود أدناه بتعيين طلب GET إلى `/api/users` وإرجاع استجابة وهمية:
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
]
}).as('getUsers')
يمكنك بعد ذلك الانتظار حتى يتم اعتراض الطلب باستخدام `cy.wait('@getUsers')` والتحقق من أن تطبيقك يعالج الاستجابة الوهمية بشكل صحيح.
العمل مع التخزين المحلي وملفات تعريف الارتباط
يوفر Cypress أوامر للتفاعل مع التخزين المحلي وملفات تعريف الارتباط. يمكنك استخدام هذه الأوامر لتعيين التخزين المحلي وملفات تعريف الارتباط والحصول عليها ومسحها في الاختبارات الخاصة بك.
لتعيين عنصر تخزين محلي، يمكنك استخدام الأمر `cy.window()` للوصول إلى كائن النافذة ثم استخدام طريقة `localStorage.setItem()`. على سبيل المثال:
cy.window().then((win) => {
win.localStorage.setItem('myKey', 'myValue')
})
للحصول على عنصر تخزين محلي، يمكنك استخدام الأمر `cy.window()` ثم استخدام طريقة `localStorage.getItem()`. على سبيل المثال:
cy.window().then((win) => {
const value = win.localStorage.getItem('myKey')
expect(value).to.equal('myValue')
})
لتعيين ملف تعريف ارتباط، يمكنك استخدام الأمر `cy.setCookie()`. على سبيل المثال:
cy.setCookie('myCookie', 'myCookieValue')
للحصول على ملف تعريف ارتباط، يمكنك استخدام الأمر `cy.getCookie()`. على سبيل المثال:
cy.getCookie('myCookie').should('have.property', 'value', 'myCookieValue')
التعامل مع تحميل الملفات
يوفر Cypress البرنامج المساعد يسمى `cypress-file-upload` الذي يبسط تحميل الملفات في الاختبارات الخاصة بك. لتثبيت البرنامج المساعد، قم بتشغيل الأمر التالي:
npm install -D cypress-file-upload
ثم، أضف السطر التالي إلى ملف `cypress/support/commands.js` الخاص بك:
import 'cypress-file-upload';
يمكنك بعد ذلك استخدام الأمر `cy.uploadFile()` لتحميل ملف. على سبيل المثال:
cy.get('input[type="file"]').attachFile('example.txt')
العمل مع IFrames
قد يكون اختبار IFrames أمرًا صعبًا، ولكن يوفر Cypress طريقة للتفاعل معها. يمكنك استخدام الأمر `cy.frameLoaded()` للانتظار حتى يتم تحميل IFrame، ثم استخدام الأمر `cy.iframe()` للحصول على كائن مستند IFrame.
cy.frameLoaded('#myIframe')
cy.iframe('#myIframe').find('button').click()
Cypress والتكامل المستمر/النشر المستمر (CI/CD)
يعد دمج Cypress في خط أنابيب CI/CD أمرًا ضروريًا لضمان جودة تطبيقك. يمكنك تشغيل اختبارات Cypress في الوضع بدون رأس في بيئة CI/CD الخاصة بك. إليك الطريقة:
- تثبيت Cypress: تأكد من تثبيت Cypress كأداة تبعية في مشروعك.
- تكوين CI/CD: قم بتكوين خط أنابيب CI/CD لتشغيل اختبارات Cypress بعد كل بناء.
- تشغيل Cypress بدون رأس: استخدم الأمر `cypress run` لتشغيل اختبارات Cypress في الوضع بدون رأس.
مثال لتكوين CI/CD (باستخدام GitHub Actions):
name: Cypress Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: npm install
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'http://localhost:3000'
سيعمل هذا التكوين على تشغيل اختبارات Cypress كلما تم دفع التعليمات البرمجية إلى فرع `main` أو تم إنشاء طلب سحب مقابل فرع `main`. يعمل الإجراء `cypress-io/github-action` على تبسيط عملية تشغيل اختبارات Cypress في GitHub Actions.
تصحيح اختبارات Cypress
يوفر Cypress أدوات تصحيح ممتازة لمساعدتك في تحديد المشكلات وإصلاحها في الاختبارات الخاصة بك. فيما يلي بعض النصائح لتصحيح اختبارات Cypress:
- استخدم Cypress Test Runner: يوفر Cypress Test Runner واجهة مرئية لتشغيل الاختبارات وتصحيحها. يمكنك التنقل عبر الاختبارات الخاصة بك أمرًا تلو الآخر، وفحص حالة التطبيق، وعرض رسائل الخطأ التفصيلية.
- استخدم الأمر `cy.pause()`: يوقف الأمر `cy.pause()` تنفيذ الاختبار الخاص بك ويسمح لك بفحص حالة التطبيق في أدوات مطور المتصفح.
- استخدم الأمر `cy.debug()`: يطبع الأمر `cy.debug()` العنصر المحدد على وحدة التحكم، مما يسمح لك بفحص خصائصه وسماته.
- استخدم أدوات مطور المتصفح: توفر أدوات مطور المتصفح ثروة من المعلومات حول تطبيقك، بما في ذلك DOM وطلبات الشبكة وسجلات وحدة التحكم.
- اقرأ رسائل الخطأ بعناية: يوفر Cypress رسائل خطأ تفصيلية يمكن أن تساعدك في تحديد سبب الخطأ. انتبه إلى رسالة الخطأ وتتبع المكدس.
Cypress مقابل أطر اختبار أخرى
في حين أن Cypress هو إطار عمل اختبار شامل قوي، فمن الضروري فهم كيفية مقارنته بالخيارات الشائعة الأخرى. إليك نظرة عامة موجزة:
- Selenium: Selenium هو إطار عمل اختبار أتمتة مستخدم على نطاق واسع. على الرغم من كونه مرنًا ويدعم لغات متعددة، إلا أنه قد يكون معقدًا في الإعداد والصيانة. يوفر Cypress تجربة أبسط وأكثر سهولة للمطورين، خاصة للتطبيقات المستندة إلى JavaScript.
- Puppeteer: Puppeteer عبارة عن مكتبة Node توفر واجهة برمجة تطبيقات عالية المستوى للتحكم في Chrome أو Chromium بدون رأس. إنه ممتاز لكشط المهام وأتمتة المتصفح ولكنه قد يتطلب تكوينًا يدويًا أكثر مقارنة بـ Cypress للاختبار الشامل.
- Playwright: Playwright هو إطار عمل أتمتة عبر المتصفحات تم تطويره بواسطة Microsoft. يشارك أوجه التشابه مع Puppeteer ولكنه يوفر دعمًا أوسع للمتصفح. يتمتع Cypress ببرنامج تصحيح أخطاء فريد من نوعه ويوفر تجربة اختبار أكثر تكاملاً.
يعتمد اختيار إطار العمل على الاحتياجات والمتطلبات المحددة لمشروعك. يعتبر Cypress اختيارًا ممتازًا لتطبيقات الويب الحديثة التي تتطلب اختبارًا شاملاً سريعًا وموثوقًا وسهل الاستخدام للمطورين.
أمثلة واقعية لـ Cypress قيد التشغيل
دعنا نستكشف بعض الأمثلة الواقعية لكيفية استخدام Cypress لاختبار أنواع مختلفة من تطبيقات الويب:
اختبار تطبيق تجارة إلكترونية
يمكنك استخدام Cypress لاختبار تدفقات المستخدم المختلفة في تطبيق التجارة الإلكترونية، مثل:
- البحث عن المنتجات
- إضافة منتجات إلى سلة التسوق
- تسجيل الخروج وتقديم طلب
- إدارة إعدادات الحساب
فيما يلي مثال على اختبار Cypress يتحقق من أنه يمكن للمستخدم إضافة منتج بنجاح إلى سلة التسوق:
it('يضيف منتجًا إلى سلة التسوق', () => {
cy.visit('/products')
cy.get('.product-card').first().find('button').click()
cy.get('.cart-count').should('have.text', '1')
})
اختبار تطبيق وسائط اجتماعية
يمكنك استخدام Cypress لاختبار تفاعلات المستخدم في تطبيق وسائط اجتماعية، مثل:
- إنشاء منشور جديد
- الإعجاب بمنشور
- التعليق على منشور
- متابعة مستخدمين آخرين
فيما يلي مثال على اختبار Cypress يتحقق من أنه يمكن للمستخدم إنشاء منشور جديد بنجاح:
it('ينشئ منشورًا جديدًا', () => {
cy.visit('/profile')
cy.get('#new-post-textarea').type('Hello, world!')
cy.get('#submit-post-button').click()
cy.get('.post').first().should('contain', 'Hello, world!')
})
اختبار تطبيق مصرفي
بالنسبة للتطبيقات المصرفية، يمكن استخدام Cypress لاختبار الوظائف الهامة مثل:
- تسجيل الدخول بشكل آمن
- التحقق من أرصدة الحسابات
- تحويل الأموال
- إدارة المستفيدين
قد يبدو الاختبار للتحقق من تحويل الأموال كما يلي (مع تحديد الطريقة المناسبة للأمان):
it('يقوم بتحويل الأموال بنجاح', () => {
cy.visit('/transfer')
cy.get('#recipient-account').type('1234567890')
cy.get('#amount').type('100')
cy.intercept('POST', '/api/transfer', { statusCode: 200, body: { success: true } }).as('transfer')
cy.get('#transfer-button').click()
cy.wait('@transfer')
cy.get('.success-message').should('be.visible')
})
الخلاصة
Cypress هو إطار عمل اختبار شامل قوي ومتعدد الاستخدامات يمكن أن يساعدك في ضمان جودة وموثوقية تطبيقات الويب الخاصة بك. تجعل واجهة برمجة التطبيقات سهلة الاستخدام للمطورين والميزات القوية والأداء الممتاز منه خيارًا شائعًا بين المطورين ومهندسي ضمان الجودة في جميع أنحاء العالم. باتباع أفضل الممارسات الموضحة في هذا الدليل، يمكنك كتابة اختبارات Cypress فعالة ستساعدك على اكتشاف الأخطاء في وقت مبكر من عملية التطوير وتقديم برامج عالية الجودة لمستخدميك.
مع استمرار تطور تطبيقات الويب، ستزداد أهمية الاختبار الشامل. سيؤدي تبني Cypress ودمجه في سير عمل التطوير إلى تمكينك من بناء تجارب ويب أكثر قوة وموثوقية وسهولة في الاستخدام.