DEV Community

Cover image for كاراتيه لاختبار API: دليل عملي لـ DSL
Yusuf Khalidd
Yusuf Khalidd

Posted on • Originally published at apidog.com

كاراتيه لاختبار API: دليل عملي لـ DSL

أنت تريد اختبارات API تُقرأ مثل خطوات واضحة، وتعيش في Git بجانب الكود، وتعمل داخل أي مسار CI. كاراتيه (Karate) مناسب لهذا النمط لأنه يتيح لك كتابة الاختبارات بملفات .feature باستخدام خطوات Given / When / Then بدل كتابة كود Java لكل حالة. في هذا الدليل ستتعلم كيف تبدأ عمليًا: هيكلة المشروع، كتابة سيناريوهات HTTP، استخدام التأكيدات، وتشغيل الاختبارات محليًا أو داخل CI.

جرب Apidog اليوم

ما هو كاراتيه

كاراتيه (Karate) هو إطار عمل مفتوح المصدر لأتمتة اختبارات API مبني على Java. تكتب الاختبارات كسيناريوهات داخل ملفات .feature باستخدام Gherkin، بنفس نمط Given / When / Then المعروف في تطوير السلوك المدفوع BDD.

الفرق العملي عن أدوات مثل Cucumber هو أنك لا تحتاج إلى كتابة كود ربط glue code لتعريف كل خطوة. كاراتيه يوفر خطوات HTTP، والتأكيدات، ومطابقة JSON، ومعالجة البيانات مدمجة. لذلك يمكن لاختبار API كامل أن يعمل بدون كتابة Java.

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

لأن الاختبارات ملفات نصية، يمكنك تخزينها في Git ومراجعتها عبر Pull Requests. أي تغيير في التأكيدات أو المسارات يظهر بوضوح في diff، وهذا يناسب سير عمل يعتمد على الكود ومدمج مع Git.

إذا كنت جديدًا على نمط Given / When / Then، فراجع مقدمتنا حول تطوير السلوك المدفوع.

كيف يعمل: ملفات الميزات و karate-config.js

يبدأ اختبار كاراتيه من ملف ميزة feature file. يحتوي الملف عادةً على:

  • كتلة Feature: لوصف المجموعة.
  • سيناريو واحد أو أكثر عبر Scenario:.
  • خطوات إعداد وتنفيذ وتأكيد باستخدام Given وWhen وThen.

مثال بسيط قابل للتشغيل:

Feature: واجهة برمجة تطبيقات المستخدم

Scenario: سرد جميع المستخدمين
  Given url 'https://jsonplaceholder.typicode.com'
  And path 'users'
  When method get
  Then status 200
  And match response == '#[10]'
Enter fullscreen mode Exit fullscreen mode

ما يحدث هنا:

  • url يحدد العنوان الأساسي.
  • path يضيف المسار /users.
  • method get يرسل طلب GET.
  • status 200 يتحقق من رمز HTTP.
  • match response == '#[10]' يؤكد أن الاستجابة مصفوفة JSON تحتوي على 10 عناصر.

الصيغة #[10] ليست JavaScript؛ إنها matcher خاص بكاراتيه للتحقق من طول المصفوفة.

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

إدارة البيئات باستخدام karate-config.js

في المشاريع الواقعية ستحتاج إلى عناوين مختلفة مثل:

  • بيئة التطوير dev
  • بيئة الاختبار qa
  • بيئة الإنتاج prod

بدل تكرار العنوان في كل ملف، استخدم karate-config.js:

function fn() {
  var env = karate.env || 'dev';

  var config = {
    baseUrl: 'https://jsonplaceholder.typicode.com'
  };

  if (env === 'qa') {
    config.baseUrl = 'https://qa.example.com';
  }

  return config;
}
Enter fullscreen mode Exit fullscreen mode

بعدها استخدم baseUrl داخل ملفات .feature:

Given url baseUrl
Enter fullscreen mode Exit fullscreen mode

وعند التشغيل مرر البيئة:

java -jar karate.jar -Dkarate.env=qa src/test/java/features
Enter fullscreen mode Exit fullscreen mode

بهذا لا تحتاج إلى تعديل ملفات الاختبار عند تبديل البيئة.

سيناريو عملي: إنشاء مستخدم

لنكتب سيناريو يتضمن جسم طلب request body ويتحقق من شكل الاستجابة:

Feature: إنشاء مستخدم

Background:
  * url baseUrl

Scenario: إنشاء مستخدم جديد يعيد 201
  Given path 'users'
  And request { name: 'Ada', job: 'engineer' }
  When method post
  Then status 201
  And match response.name == 'Ada'
  And match response.id == '#string'
Enter fullscreen mode Exit fullscreen mode

النقاط المهمة:

  • Background: يُشغّل قبل كل سيناريو في الملف.
  • * خطوة عامة يمكن استخدامها بدل Given أو When أو Then في الإعدادات.
  • request يقبل JSON مباشرة بدون serializer أو POJO.
  • #string يتحقق أن الحقل موجود ونوعه نصي، دون تثبيت قيمة محددة.

هذا مفيد عندما يعيد الخادم قيمًا مولدة مثل id أو timestamp.

التأكيدات ومطابقة JSON

الكلمة الأساسية الأكثر استخدامًا في كاراتيه هي match. تستخدمها لمقارنة القيمة الفعلية بالقيمة المتوقعة.

مطابقة كاملة

And match response == { id: '#number', name: 'Ada', job: 'engineer' }
Enter fullscreen mode Exit fullscreen mode

هنا:

  • #number يتحقق أن id رقم.
  • name يجب أن يساوي Ada.
  • job يجب أن يساوي engineer.

مطابقة جزئية باستخدام contains

إذا كانت الاستجابة تحتوي حقولًا كثيرة وتهتم بحقل واحد فقط:

And match response contains { name: 'Ada' }
Enter fullscreen mode Exit fullscreen mode

يمر الاختبار طالما أن name يساوي Ada، حتى لو تضمنت الاستجابة حقولًا إضافية.

يدعم كاراتيه أيضًا:

And match response !contains { error: true }
And match response contains only { name: 'Ada', job: 'engineer' }
And match response contains any [{ role: 'admin' }, { role: 'user' }]
And match response contains deep { profile: { active: true } }
Enter fullscreen mode Exit fullscreen mode

التحقق من المصفوفات

للتحقق من طول مصفوفة:

And match response == '#[10]'
Enter fullscreen mode Exit fullscreen mode

للتحقق من شكل كل عنصر:

And match each response == { id: '#number', name: '#string' }
Enter fullscreen mode Exit fullscreen mode

هذا السطر يتحقق أن كل عنصر داخل المصفوفة يحتوي على:

  • id رقمي
  • name نصي

بدون كتابة loops أو assertions متعددة.

للمزيد من الأنماط العملية، راجع دليلنا العملي لتأكيدات واجهة برمجة التطبيقات.

الاختبار القائم على البيانات والتكامل المستمر CI

عندما تريد تشغيل نفس السيناريو على أكثر من مدخل، استخدم Scenario Outline مع جدول Examples.

Scenario Outline: إنشاء مستخدمين من جدول
  Given url baseUrl
  And path 'users'
  And request { name: '<name>', job: '<job>' }
  When method post
  Then status 201
  And match response.name == '<name>'

  Examples:
    | name  | job       |
    | Ada   | engineer  |
    | Grace | scientist |
    | Alan  | analyst   |
Enter fullscreen mode Exit fullscreen mode

سيُشغّل كاراتيه السيناريو ثلاث مرات، مرة لكل صف.

إذا كانت البيانات كبيرة، ضعها في ملف خارجي:

Examples:
  | read('classpath:test-data/users.json') |
Enter fullscreen mode Exit fullscreen mode

يدعم كاراتيه قراءة JSON وCSV بهذه الطريقة، لذلك يمكنك إبقاء بيانات الاختبار خارج ملفات الميزات.

تشغيل كاراتيه محليًا أو داخل CI

لديك طريقتان شائعتان.

1. التشغيل عبر Maven أو Gradle

في مشروع Java، يمكنك تشغيل كاراتيه عبر JUnit 5 بإضافة تبعية karate-junit5 ثم تشغيل:

mvn test
Enter fullscreen mode Exit fullscreen mode

هذا مناسب إذا كان مشروعك يستخدم Maven أو Gradle بالفعل.

2. التشغيل عبر karate.jar

إذا لا تريد أداة بناء، استخدم ملف JAR المستقل:

java -jar karate.jar src/test/java/features
Enter fullscreen mode Exit fullscreen mode

للتشغيل حسب tag:

java -jar karate.jar --tags @smoke src/test/java/features
Enter fullscreen mode Exit fullscreen mode

للتشغيل المتوازي وتحديد مجلد التقارير:

java -jar karate.jar --tags @smoke --threads 4 --output reports src/test/java/features
Enter fullscreen mode Exit fullscreen mode

لتمرير البيئة:

java -jar karate.jar -Dkarate.env=qa src/test/java/features
Enter fullscreen mode Exit fullscreen mode

ينشئ كاراتيه تقرير HTML بعد التشغيل، ما يجعل فحص الفشل أسهل داخل مخرجات CI.

لصورة أوسع حول CI/CD، راجع كيفية أتمتة اختبارات واجهة برمجة التطبيقات في CI/CD.

نقاط القوة والمقايضات

نقاط القوة

كاراتيه مفيد عندما تريد:

  • اختبارات API تُقرأ بوضوح.
  • ملفات نصية قابلة للمراجعة داخل Git.
  • تأكيدات JSON قوية بدون كتابة كود كثير.
  • دعم matchers مثل #string و#number وeach.
  • تشغيل بدون واجهة رسومية داخل CI.
  • إمكانية التوسع لاحقًا إلى mocks أو performance tests.

المقايضات

لكن هناك نقاط يجب حسابها:

  • تحتاج إلى Java لأن كاراتيه يعمل على JVM.
  • DSL الخاص بكاراتيه يحتاج إلى تعلم.
  • إعادة الاستخدام المتقدم قد يدفعك إلى JavaScript أو Java.
  • غير المطورين قد يجدون صعوبة في تعديل الاختبارات مباشرة داخل Git.

بمعنى آخر: كاراتيه مناسب جدًا للفرق التي تفضل نهجًا قائمًا على الكود.

كاراتيه مقابل نهج بدون كود مثل Apidog

كاراتيه يعتمد على الكود. تكتب ملفات .feature، تحفظها في Git، وتشغلها من Maven أو Gradle أو JAR. هذا يناسب المطورين الذين يريدون اختبارات قريبة من الكود وتحت نظام التحكم بالإصدار.

Apidog يأخذ مسارًا مرئيًا بدون كود. تبني سيناريوهات الاختبار في واجهة المستخدم، تربط الطلبات، وتضيف التأكيدات بالنقر بدل كتابة DSL. ولأن دورة حياة API تشمل التصميم، التصحيح، المحاكاة، والتوثيق في مكان واحد، يمكن للاختبارات إعادة استخدام نقاط النهاية والمخططات التي عرّفتها مسبقًا.

يمكن تشغيل مجموعات Apidog بدون واجهة رسومية داخل CI عبر Apidog CLI.

ثبّت CLI باستخدام Node:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

ثم شغّل سيناريو أو مجموعة اختبار محفوظة:

apidog run --access-token "$APIDOG_ACCESS_TOKEN" -t <scenarioOrSuiteId> -e <environmentId> -r cli,html,junit
Enter fullscreen mode Exit fullscreen mode

معاني الخيارات:

  • -t يحدد سيناريو أو مجلدًا أو مجموعة اختبار.
  • -e يحدد البيئة.
  • -r يحدد نوع التقرير مثل cli أو html أو json أو junit.
  • -d أو --iteration-data يمرر ملف بيانات أو معرف بيانات اختبار للتشغيل القائم على البيانات.

واجهة CLI تعمل headless داخل أي خطوة CI يمكنها تشغيل Node. وهي تشغل سيناريوهات Apidog المحفوظة لديك، وليست مولد تحميل أو مرسل طلبات تفاعلي.

للتفاصيل، راجع واجهة سطر أوامر Apidog للتكامل المستمر والتسليم المستمر، وكذلك واجهة سطر أوامر Apidog مقابل نيومان.

الخلاصة: كلا النهجين يشغل اختبارات API مؤتمتة داخل CI. الفرق في طريقة التأليف:

  • كاراتيه: اكتب DSL في Git.
  • Apidog: أنشئ السيناريوهات بصريًا ثم شغلها عبر CLI.

كيف تختار

اختر كاراتيه إذا كان فريقك:

  • يعتمد على المطورين بشكل أساسي.
  • مرتاحًا مع JVM.
  • يريد اختبارات محفوظة ككود بجانب التطبيق.
  • يفضل مراجعة الاختبارات عبر Pull Requests.
  • يحتاج إلى DSL قوي لمطابقة JSON.

اختر أداة بدون كود مثل Apidog إذا كان فريقك:

  • يضم QA أو Product يريدون المشاركة في بناء الاختبارات.
  • يريد ربط الاختبارات بالتصميم والتوثيق.
  • لا يريد صيانة مشروع Java لتشغيل فحوصات API.
  • يحتاج إلى تشغيل CI عبر CLI مع واجهة تأليف مرئية.

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

إذا كنت تقارن الخيارات، فراجع دليلنا حول كيفية اختيار إطار عمل لأتمتة اختبار واجهة برمجة التطبيقات.

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

هل أحتاج إلى معرفة Java لاستخدام كاراتيه؟

لا، ليس لكتابة اختبارات API الأساسية. تكتب الاختبارات باستخدام Gherkin DSL، وكاراتيه يوفر خطوات HTTP والتأكيدات مدمجة. لكنك تحتاج إلى تثبيت Java لتشغيل الاختبارات، وقد تحتاج إلى Java أو JavaScript عند بناء مساعدات مخصصة أو منطق إعادة استخدام متقدم.

كيف يختلف كاراتيه عن Cucumber؟

كلاهما يستخدم Given / When / Then. في Cucumber تكتب step definitions لدعم الخطوات. في كاراتيه، خطوات API جاهزة، لذلك لا تحتاج إلى glue code لاختبارات HTTP القياسية.

هل يمكن تشغيل كاراتيه بدون Maven أو Gradle؟

نعم. استخدم ملف karate.jar المستقل:

java -jar karate.jar <path>
Enter fullscreen mode Exit fullscreen mode

ويمكنك استخدام tags، والتشغيل المتوازي، وتحديد مجلد إخراج بدون أداة بناء.

ماذا تعني #string و#[10]؟

هذه matchers في كاراتيه.

#string يتحقق أن الحقل نصي، و#number يتحقق أنه رقم، و#[10] يتحقق أن المصفوفة تحتوي على 10 عناصر.

هل يمكن لاختبارات API بدون كود أن تعمل داخل CI؟

نعم. أدوات مثل Apidog تتيح تأليف الاختبارات بصريًا ثم تشغيلها headless عبر CLI داخل CI باستخدام Node.

Top comments (0)