DEV Community

Cover image for دليل عملي لاختبار التحميل لواجهات API باستخدام أرتيلري
Yusuf Khalidd
Yusuf Khalidd

Posted on • Originally published at apidog.com

دليل عملي لاختبار التحميل لواجهات API باستخدام أرتيلري

Artillery هي مجموعة أدوات مفتوحة المصدر لاختبار التحميل مبنية على Node.js. تتيح لك توليد حركة مرور عالية التزامن على واجهة برمجة التطبيقات (API) من خلال ملف YAML بسيط: تحدد مراحل التحميل، تصف تدفقات الطلبات، تشغل artillery run script.yml، ثم تقرأ نسب زمن الاستجابة المئوية، معدلات الطلبات، وعدد الأخطاء. يشرح هذا الدليل طريقة تثبيت Artillery v2، كتابة اختبار عملي، تشغيله، استخراج النتائج بالطريقة الصحيحة في v2، وربطه بمسار CI.

جرّب Apidog اليوم

ما هو Artillery ومتى تستخدمه؟

ينشئ Artillery مستخدمين افتراضيين (VUs) يرسلون طلبات إلى نقاط النهاية لديك ويقيسون قدرة النظام على تحمل الحمل المستمر. المستخدم الافتراضي هو عميل مُحاكى ينفذ سيناريو خطوة بخطوة، كما يفعل مستخدم أو خدمة حقيقية.

استخدم Artillery عندما تريد إجابات عملية على أسئلة الأداء مثل:

  • كيف يتغير زمن الاستجابة p95 عند 50 طلبًا في الثانية؟
  • عند أي معدل وصول تبدأ الأخطاء بالظهور؟
  • هل تبقى واجهة API مستقرة لمدة 5 دقائق من الحمل المستمر؟
  • هل يتدهور الأداء تدريجيًا مع استمرار الضغط؟

الميزة الأساسية في Artillery أن الاختبار تصريحي. بدل كتابة حلقات تزامن يدويًا، تصف شكل الحمل في YAML. وبما أنه يعمل فوق Node.js، يمكنك تشغيل نفس الاختبار محليًا وفي CI.

إذا كنت تقارن الأدوات، راجع ملخص أفضل أدوات اختبار التحميل ومقارنة برامج اختبار التحميل لفهم الفروقات بين k6 وJMeter وGatling وغيرها.

تثبيت Artillery v2

اسم الحزمة هو artillery، والإصدار الرئيسي الحالي هو v2. ثبته عالميًا عبر npm:

npm install -g artillery@latest
artillery version
Enter fullscreen mode Exit fullscreen mode

تحتاج إلى إصدار LTS حديث من Node.js. يعمل Artillery على Windows وmacOS وLinux.

إذا كنت لا تريد تثبيت الحزمة عالميًا، استخدم npx:

npx artillery@latest run script.yml
Enter fullscreen mode Exit fullscreen mode

كتابة اختبار Artillery

يتكون ملف الاختبار من قسمين أساسيين:

  • config: يحدد الهدف ومراحل الحمل والمتغيرات.
  • scenarios: يحدد ما يفعله كل مستخدم افتراضي.

مثال كامل:

config:
  target: "https://api.example.com"
  phases:
    - name: "Warm up"
      duration: 60
      arrivalRate: 5
    - name: "Ramp to peak"
      duration: 120
      arrivalRate: 5
      rampTo: 50
    - name: "Sustained load"
      duration: 300
      arrivalRate: 50
      maxVusers: 500

  variables:
    productId:
      - "1001"
      - "1002"

scenarios:
  - name: "Browse and create order"
    flow:
      - get:
          url: "/v1/products/{{ productId }}"
      - post:
          url: "/v1/orders"
          json:
            productId: "{{ productId }}"
            quantity: 2
Enter fullscreen mode Exit fullscreen mode

فهم قسم config

config.target هو المضيف الأساسي الذي تُرسل إليه الطلبات. أي url داخل السيناريو يُضاف إلى هذا الأساس.

مثال:

target: "https://api.example.com"
Enter fullscreen mode Exit fullscreen mode

مع:

url: "/v1/products/1001"
Enter fullscreen mode Exit fullscreen mode

ينتج عنه الطلب:

https://api.example.com/v1/products/1001
Enter fullscreen mode Exit fullscreen mode

أهم مفاتيح phases

config.phases هي مصفوفة مراحل تُنفذ بالترتيب:

phases:
  - duration: 60
    arrivalRate: 5
  - duration: 120
    arrivalRate: 5
    rampTo: 50
Enter fullscreen mode Exit fullscreen mode

المفاتيح الأكثر استخدامًا:

  • duration: مدة المرحلة بالثواني أو كسلسلة مثل "5m".
  • arrivalRate: عدد المستخدمين الافتراضيين الجدد في كل ثانية.
  • rampTo: رفع معدل الوصول تدريجيًا حتى هذه القيمة.
  • arrivalCount: عدد ثابت من المستخدمين الافتراضيين موزع على المرحلة.
  • maxVusers: الحد الأعلى للمستخدمين الافتراضيين المتزامنين.
  • name: اسم المرحلة في الإخراج.

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

فهم قسم scenarios

scenarios هي قائمة بالسيناريوهات. كل سيناريو يحتوي على flow، وهي خطوات HTTP ينفذها المستخدم الافتراضي بالترتيب.

مثال:

scenarios:
  - name: "Login and fetch profile"
    flow:
      - post:
          url: "/login"
          json:
            email: "user@example.com"
            password: "secret"
      - get:
          url: "/profile"
Enter fullscreen mode Exit fullscreen mode

أفعال HTTP المدعومة تشمل:

  • get
  • post
  • put
  • patch
  • delete

لإرسال جسم JSON:

- post:
    url: "/v1/orders"
    json:
      productId: "{{ productId }}"
      quantity: 2
Enter fullscreen mode Exit fullscreen mode

وتُستخدم صيغة {{ variableName }} لقراءة المتغيرات.

يمكنك أيضًا استخدام weight لتحديد احتمالية اختيار سيناريو معين:

scenarios:
  - name: "Browse"
    weight: 80
    flow:
      - get:
          url: "/products"

  - name: "Create order"
    weight: 20
    flow:
      - post:
          url: "/orders"
          json:
            productId: "1001"
Enter fullscreen mode Exit fullscreen mode

تمرير بيانات الاختبار من CSV

القيم الثابتة مناسبة لاختبار دخان بسيط، لكنها لا تكفي لمحاكاة استخدام واقعي. لاستخدام بيانات متعددة، استخدم config.payload.

ملف users.csv مثلًا:

email,password
user1@example.com,password1
user2@example.com,password2
Enter fullscreen mode Exit fullscreen mode

ملف Artillery:

config:
  target: "https://api.example.com"
  payload:
    path: "./users.csv"
    fields:
      - "email"
      - "password"
  phases:
    - duration: 120
      arrivalRate: 20

scenarios:
  - name: "Login"
    flow:
      - post:
          url: "/login"
          json:
            email: "{{ email }}"
            password: "{{ password }}"
Enter fullscreen mode Exit fullscreen mode

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

تشغيل الاختبار

الأمر الأساسي:

artillery run script.yml
Enter fullscreen mode Exit fullscreen mode

لتجاوز الهدف دون تعديل الملف:

artillery run --target https://staging.example.com script.yml
Enter fullscreen mode Exit fullscreen mode

أو بالاختصار:

artillery run -t https://staging.example.com script.yml
Enter fullscreen mode Exit fullscreen mode

لتمرير متغيرات من سطر الأوامر:

artillery run -v '{ "productId": ["1001","1002"] }' script.yml
Enter fullscreen mode Exit fullscreen mode

علامات مفيدة:

  • --target أو -t: تجاوز config.target.
  • --environment أو -e: اختيار بيئة من config.environments.
  • --config أو -c: تحميل إعدادات من ملف منفصل.
  • --insecure أو -k: تجاهل تحقق TLS في بيئات الاختبار ذات الشهادات الموقعة ذاتيًا.

مثال لاستخدام البيئات:

config:
  target: "https://api.example.com"
  environments:
    staging:
      target: "https://staging.example.com"
    production:
      target: "https://api.example.com"
  phases:
    - duration: 60
      arrivalRate: 10

scenarios:
  - flow:
      - get:
          url: "/health"
Enter fullscreen mode Exit fullscreen mode

تشغيل بيئة staging:

artillery run -e staging script.yml
Enter fullscreen mode Exit fullscreen mode

قراءة النتائج

أثناء التشغيل، يطبع Artillery مقاييس مجمعة كل 10 ثوانٍ تقريبًا. في النهاية، يظهر ملخص يتضمن أهم المؤشرات.

ركز على:

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

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

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

إنشاء تقرير في Artillery v2

تغيرت آلية التقارير في Artillery عبر الإصدارات، وهذه نقطة تسبب لبسًا شائعًا.

في الإصدارات القديمة، كانت بعض الشروحات تستخدم:

artillery run --output report.json script.yml
artillery report report.json
Enter fullscreen mode Exit fullscreen mode

الجزء الأول ما زال يعمل. أما artillery report فلم يعد يعمل في Artillery v2 الحالي.

لإنشاء ملف نتائج JSON:

artillery run --output report.json script.yml
Enter fullscreen mode Exit fullscreen mode

هذا ينتج ملفًا قابلًا للقراءة آليًا يمكن استخدامه في CI أو تحليله بأدوات مثل jq.

مثال لاستخراج p95:

jq '.aggregate.summaries["http.response_time"].p95' report.json
Enter fullscreen mode Exit fullscreen mode

لديك 3 خيارات عملية بدل تقرير HTML القديم:

1. تحليل JSON بنفسك

مناسب لمسارات CI، حيث تريد فشل المهمة إذا تجاوز الأداء حدًا معينًا.

مثال:

P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)

echo "p95 = $P95 ms"

if (( $(echo "$P95 > 500" | bc -l) )); then
  echo "p95 exceeded budget"
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

2. استخدام Artillery Cloud

إذا كنت تريد لوحة تحكم مستضافة:

artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
Enter fullscreen mode Exit fullscreen mode

3. إرسال المقاييس إلى نظام المراقبة

يمكنك دفع المقاييس إلى مكدس المراقبة لديك باستخدام publish-metrics أو OpenTelemetry، بحيث تظهر أزمنة الاستجابة ومعدلات الأخطاء في نفس لوحات الإنتاج.

تشغيل Artillery في CI

بما أن Artillery عبارة عن CLI مبني على Node.js، يمكن تشغيله بسهولة داخل GitHub Actions أو أي نظام CI.

مثال GitHub Actions:

name: Load test

on: [workflow_dispatch]

jobs:
  artillery:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "lts/*"

      - run: npm install -g artillery@latest

      - run: artillery run --output report.json script.yml

      - uses: actions/upload-artifact@v4
        with:
          name: artillery-report
          path: report.json
Enter fullscreen mode Exit fullscreen mode

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

لإضافة حد أداء يفشل المهمة عند تجاوزه:

      - name: Check p95 latency
        run: |
          P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
          echo "p95 = $P95 ms"

          if (( $(echo "$P95 > 500" | bc -l) )); then
            echo "p95 exceeded 500ms"
            exit 1
          fi
Enter fullscreen mode Exit fullscreen mode

أين تتلاءم Apidog: الاختبار الوظيفي وحماية CI

تجيب Artillery على سؤال:

هل يمكن لواجهة API تحمل هذا القدر من حركة المرور؟

وهذا هو اختبار التحميل والأداء.

لكن هناك سؤالًا آخر لا يقل أهمية:

هل ما زالت واجهة API تُرجع الاستجابات الصحيحة بعد تغيير الكود؟

هذا هو الاختبار الوظيفي واختبار الانحدار، وهنا يأتي دور Apidog.

Apidog هي منصة API شاملة للتصميم، التصحيح، المحاكاة، التوثيق، والاختبار الآلي. يمكن استخدام سيناريوهات الاختبار لتجميع نقاط النهاية في خطوات منطقية، والتحقق من أكواد الحالة، أجسام الاستجابة، والعقود.

كن واضحًا بشأن الحدود: تتضمن Apidog ميزة اختبار أداء، لكنها محدودة بحد أقصى 100 مستخدم افتراضي. هذا مفيد لاكتشاف الانحدارات الواضحة، لكنه ليس بديلًا عن Artillery عندما تحتاج إلى تزامن عالٍ أو حمل موزع واسع. للمزيد، راجع اختبار تحميل واجهات برمجة التطبيقات بدون Python واختبار أداء API في Apidog.

الاستخدام العملي:

  • استخدم Artillery لاختبار قابلية التوسع تحت الحمل.
  • استخدم Apidog CLI لاختبارات وظيفية وانحدارية داخل CI.

تثبيت Apidog CLI:

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

تشغيل سيناريو اختبار في CI:

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <TEST_SCENARIO_ID> \
  -e <ENVIRONMENT_ID> \
  -r cli,junit \
  --out-dir ./apidog-reports
Enter fullscreen mode Exit fullscreen mode

شرح العلامات:

  • --access-token: رمز الوصول إلى Apidog.
  • -t: معرف سيناريو الاختبار.
  • -e: معرف البيئة.
  • -r cli,junit: إخراج للكونسول وتقرير JUnit XML.
  • --out-dir: مجلد حفظ التقارير.

لشرح تفصيلي، راجع البرنامج التعليمي لواجهة سطر أوامر Apidog، ولتصميم مسارات CI/CD، راجع أفضل الممارسات لـ CI/CD لاختبار API.

إذا كنت تريد حماية CI باختبارات وظيفية وتعاقدية بجانب اختبارات تحميل Artillery، يمكنك استخدام Apidog لبناء سيناريوهات تحقق قابلة للتشغيل تلقائيًا.

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

ما هو اختبار التحميل باستخدام Artillery؟

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

هل Artillery مجانية ومفتوحة المصدر؟

نعم. واجهة سطر أوامر Artillery الأساسية مجانية ومفتوحة المصدر، وتتوفر عبر npm باسم artillery. توجد أيضًا خدمة مدفوعة مستضافة باسم Artillery Cloud لتوفير لوحات نتائج، لكن يمكنك تشغيل اختبارات تحميل كاملة محليًا وفي CI بدونها.

كيف تشغل اختبار تحميل باستخدام Artillery؟

ثبّت Artillery:

npm install -g artillery@latest
Enter fullscreen mode Exit fullscreen mode

اكتب ملف YAML يحتوي على config وscenarios، ثم شغله:

artillery run script.yml
Enter fullscreen mode Exit fullscreen mode

سيطبع Artillery مقاييس مباشرة أثناء التشغيل وملخصًا عند الانتهاء.

كيف تُنشئ تقرير Artillery؟

استخدم:

artillery run --output report.json script.yml
Enter fullscreen mode Exit fullscreen mode

هذا ينتج ملف JSON قابلًا للتحليل. أمر artillery report القديم الذي كان ينتج HTML تمت إزالته من Artillery CLI. بدلًا من ذلك، حلل JSON باستخدام jq، أو استخدم Artillery Cloud، أو ادفع المقاييس إلى نظام المراقبة لديك.

Artillery مقابل k6 أو JMeter: أيهم تختار؟

كل الأدوات الثلاثة مناسبة لاختبارات تحميل واسعة، لكن نموذج الاستخدام مختلف:

  • Artillery يستخدم YAML وNode.js، وهو مناسب للفرق القريبة من منظومة JavaScript.
  • k6 يستخدم JavaScript بنموذج code-first.
  • JMeter يعتمد على واجهة رسومية ويستند إلى Java وله تاريخ طويل من الإضافات.

للمقارنة الأعمق، راجع مقارنة Gatling vs JMeter. اختر الأداة التي تناسب طريقة عمل فريقك، ثم أضف اختبارات وظيفية في CI لتغطية السلوك الصحيح بجانب الأداء.

Top comments (0)