DEV Community

Cover image for استراتيجيات اختبار API: دليل عملي لضمان موثوقية واجهات برمجة التطبيقات
Yusuf Khalidd
Yusuf Khalidd

Posted on • Originally published at apidog.com

استراتيجيات اختبار API: دليل عملي لضمان موثوقية واجهات برمجة التطبيقات

معظم أخطاء واجهات برمجة التطبيقات (API) ليست معقدة: حقل مفقود، رمز حالة غير صحيح، مهلة تحت الحمل، أو تغيير كاسر تم شحنه لأن أحداً لم يتحقق من العقد. الاختبار المخصص قد يلتقط بعضها بالصدفة، لكن استراتيجية الاختبار تلتقطها بشكل مقصود وقابل للتكرار.

جرّب Apidog اليوم

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

ماذا تعني استراتيجية اختبار واجهات برمجة التطبيقات فعلياً

قبل أن تكتب أي assertion، أجب عن أربعة أسئلة:

1. ماذا تختبر؟

ابدأ بنقاط النهاية والتدفقات ذات القيمة التجارية الأعلى.

مثلاً:

  • واجهة الدفع أهم من health-check.
  • إنشاء الطلب أهم من جلب قائمة تصنيفات ثابتة.
  • تغيير كلمة المرور أهم من endpoint عام للقراءة فقط.

رتّب التغطية حسب:

  • المخاطر
  • حجم المرور
  • حساسية البيانات
  • تأثير الفشل على المستخدم أو العمل

2. في أي طبقة تختبر؟

ليست كل الفحوصات يجب أن تكون end-to-end.

  • تحقق بسيط من GET /users/{id} يمكن أن يكون اختبار طلب واحد.
  • تدفق إنشاء طلب ثم دفعه يحتاج اختبار تكامل أو end-to-end.
  • توافق شكل الاستجابة بين مزود ومستهلك يحتاج اختبار عقد.

كلما وضعت الفحص في طبقة أعلى، أصبح أبطأ وأكثر هشاشة.

3. متى يتم تشغيل الاختبار؟

قسّم الاختبارات حسب السرعة والكلفة:

  • اختبارات سريعة: مع كل push أو pull request.
  • اختبارات متوسطة: ليلاً أو قبل الدمج.
  • اختبارات ثقيلة مثل load/security: قبل الإصدار أو وفق جدول.

4. ماذا يعني النجاح؟

اختبار يتحقق فقط من 200 OK ضعيف جداً.

عرّف النجاح بوضوح:

  • رمز الحالة المتوقع
  • شكل الاستجابة schema
  • الحقول المطلوبة
  • القيم المهمة
  • زمن الاستجابة المقبول
  • رسائل الخطأ عند الفشل

مثال:

GET /api/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer <token>
Enter fullscreen mode Exit fullscreen mode

تأكيدات أفضل:

  • الحالة هي 200.
  • الجسم يطابق مخطط User.
  • الحقل id يساوي 42.
  • الحقل email موجود وبصيغة بريد إلكتروني صحيحة.
  • زمن الاستجابة أقل من حد متفق عليه.

لماذا تتفوق الاستراتيجية على الاختبار المخصص Ad-Hoc Testing

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

المشكلة 1: لا يتكرر

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

الاختبار الآلي المحفوظ يعمل بنفس المدخلات والتأكيدات في كل مرة.

المشكلة 2: يميل إلى المسار السعيد

في الاختبار اليدوي غالباً تختبر ما تتوقع أنه يعمل:

  • طلب صحيح
  • token صالح
  • بيانات طبيعية
  • حمولة صغيرة

لكن الإنتاج يكسر واجهتك عبر الحالات الأقل مثالية:

  • token منتهي
  • حقل مطلوب مفقود
  • كمية سالبة
  • قائمة تحتوي آلاف العناصر
  • مستخدم يحاول الوصول إلى بيانات لا يملكها

المشكلة 3: لا يتوسع

إذا كان لديك:

  • 40 endpoint
  • 5 بيئات

فهذا يعني 200 فحص يدوي محتمل لكل إصدار. عملياً لن يحدث ذلك.

الاستراتيجية تحول الجهد إلى استثمار: تكتب الاختبار مرة، ثم يعمل مع كل تغيير.

هرم اختبار واجهات برمجة التطبيقات

استخدم هرم الاختبار لتحديد أين تضع معظم التغطية:

        /\
       /  \      اختبارات شاملة / تدفق العمل
      /----\     قليلة، بطيئة، عالية القيمة
     /      \
    /--------\   اختبارات التكامل / العقد
   /          \  متوسطة العدد والسرعة
  /____________\
                اختبارات الطلب الواحد / الوحدة
                كثيرة، سريعة، رخيصة
Enter fullscreen mode Exit fullscreen mode

الطبقة السفلية: فحوصات الطلب الواحد

كل اختبار يضرب endpoint واحداً ويتحقق من الاستجابة.

مثال:

GET /api/products/123 HTTP/1.1
Host: api.example.com
Enter fullscreen mode Exit fullscreen mode

تحقق من:

  • status code
  • schema
  • القيم الأساسية
  • الأخطاء المتوقعة

هذه الاختبارات يجب أن تكون الأكثر عدداً لأنها:

  • سريعة
  • سهلة التصحيح
  • قليلة الاعتماد على أنظمة أخرى

الطبقة الوسطى: اختبارات التكامل والعقد

تتحقق من أن الخدمات تعمل معاً وأن شكل البيانات المتبادلة صحيح.

مثال:

  • إنشاء طلب في خدمة الطلبات
  • إرسال الدفع إلى مزود خارجي أو خدمة دفع
  • تحديث حالة الطلب

هذه الاختبارات أبطأ لأنها تشمل أكثر من مكون، لكنها تلتقط أخطاء لا تظهر في اختبار endpoint منفرد.

الطبقة العليا: تدفقات End-to-End

تشغل رحلة كاملة:

  1. إنشاء مستخدم
  2. إنشاء طلب
  3. الدفع
  4. التحقق من حالة الطلب
  5. إرسال إشعار

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

الخطأ الشائع هو عكس الهرم: عدد كبير من اختبارات end-to-end البطيئة وقليل من الاختبارات السريعة. النتيجة: feedback loop بطيء وفشل متقلب.

أنواع الاختبارات ومتى تستخدم كل نوع

استراتيجية API الجيدة تستخدم أكثر من نوع اختبار، وكل نوع يستهدف فئة مختلفة من الأخطاء.

نوع الاختبار ماذا يلتقط؟ متى يعمل؟
وظيفي status خاطئ، schema، قيم غير صحيحة مع كل commit
تكامل فشل تدفقات بين خدمات مع كل commit أو ليلاً
انحدار سلوك كان يعمل ثم تعطل مع كل commit وقبل الإصدار
عقد تغييرات كاسرة في الواجهة مع كل تغيير على المزود
تحميل بطء وفشل تحت الضغط قبل الإطلاق وبشكل مجدول
أمان مصادقة، تفويض، حقن، كشف بيانات قبل الإصدار وبشكل مجدول

الاختبار الوظيفي

يتحقق من أن endpoint تنفذ ما تنص عليه المواصفات.

مثال:

POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "Ali",
  "email": "ali@example.com"
}
Enter fullscreen mode Exit fullscreen mode

التوقعات:

  • الحالة 201.
  • الجسم يحتوي id.
  • الحقل email يساوي البريد المرسل.
  • الاستجابة تطابق schema المستخدم.

لشرح أعمق، راجع الاختبار الوظيفي لواجهة برمجة التطبيقات.

اختبار التكامل

يتحقق من أن واجهتك تعمل بشكل صحيح مع التبعيات:

  • قاعدة البيانات
  • خدمة الدفع
  • خدمة بريد
  • message queue
  • خدمة داخلية أخرى

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

راجع اختبار التكامل لواجهة برمجة التطبيقات.

اختبار الانحدار

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

شغّله:

  • مع كل pull request
  • قبل الإصدار
  • بعد refactor كبير
  • بعد تغيير في contract أو database schema

راجع اختبار الانحدار.

اختبار العقد

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

يلتقط مثلاً:

  • تغيير اسم حقل
  • حذف حقل يعتمد عليه المستهلك
  • تغيير نوع id من string إلى number
  • حذف endpoint
  • تغيير status code متوقع

إذا كانت فرق أو عملاء آخرون يستهلكون API الخاصة بك، فاختبار العقد ضروري.

راجع اختبار عقد واجهة برمجة التطبيقات.

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

يقيس كيف تتصرف API تحت حركة مرور متزامنة.

راقب:

  • p95 latency
  • p99 latency
  • معدل الأخطاء
  • throughput
  • نقطة الانهيار
  • استهلاك الموارد

لا تشغله مع كل commit. شغّله:

  • قبل الإطلاق
  • قبل حملة أو حدث متوقع
  • أسبوعياً أو شهرياً لاكتشاف التدهور

راجع أدوات اختبار التحميل.

اختبار الأمان

يتحقق من أن API ترفض الطلبات غير المسموح بها.

غطِ على الأقل:

  • طلب بدون token => 401
  • token بصلاحيات خاطئة => 403
  • محاولة قراءة بيانات مستخدم آخر => 403 أو 404
  • مدخلات حقن SQL/NoSQL
  • أحجام payload غير طبيعية
  • كشف بيانات حساسة في الاستجابة

راجع اختبار أمان واجهة برمجة التطبيقات.

الحالات الإيجابية والسلبية والحالات القصوى

لكل endpoint، اكتب ثلاثة أنواع من الحالات.

1. الحالات الإيجابية

مدخلات صالحة وتوقع نجاحاً.

مثال:

POST /api/orders HTTP/1.1
Content-Type: application/json

{
  "customerId": "c_123",
  "quantity": 2
}
Enter fullscreen mode Exit fullscreen mode

المتوقع:

  • status 201
  • إنشاء الطلب
  • وجود orderId
  • الكمية تساوي 2

2. الحالات السلبية

مدخلات غير صالحة وتوقع فشلاً نظيفاً.

مثال:

POST /api/orders HTTP/1.1
Content-Type: application/json

{
  "customerId": "c_123",
  "quantity": -5
}
Enter fullscreen mode Exit fullscreen mode

المتوقع:

  • status 400
  • رسالة خطأ واضحة
  • الخطأ يذكر quantity
  • لا يتم إنشاء طلب

إذا أعاد الطلب 201 أو 500، فهذا خطأ حقيقي لم يكن اختبار happy path سيلتقطه.

أمثلة أخرى:

الحالة المتوقع
حقل مطلوب مفقود 400
token مفقود 401
صلاحية غير كافية 403
مورد غير موجود 404
نوع بيانات غير صحيح 400

3. الحالات القصوى Edge Cases

اختبر حدود المدخلات الصالحة:

  • قائمة فارغة
  • قائمة ضخمة
  • نص بطول الحد الأقصى
  • صفر
  • رقم سالب إن لم يكن مسموحاً
  • Unicode
  • timestamp عند حدود التوقيت الصيفي
  • قيمة null
  • مسافات فقط في النصوص

قاعدة عملية: لكل اختبار إيجابي، اكتب اختباراً سلبياً واحداً على الأقل.

بيانات الاختبار والبيئات

الاختبارات تكون موثوقة فقط إذا كانت البيانات والبيئة موثوقتين.

استخدم بيانات اختبار مخصصة

لا تعتمد على سجلات إنتاج أو صفوف موجودة مسبقاً.

بدلاً من ذلك:

  • أنشئ البيانات داخل الاختبار.
  • أو ازرع seed data في بداية التشغيل.
  • أو استخدم fixtures معروفة.
  • أو استخدم data generator.

راجع كيفية إنشاء بيانات اختبار API واقعية.

اجعل الاختبارات مستقلة

لا تجعل اختباراً يعتمد على نتيجة اختبار سابق.

سيئ:

  1. اختبار A ينشئ مستخدماً.
  2. اختبار B يفترض أن المستخدم موجود.
  3. إذا تغيّر ترتيب التشغيل، يفشل B.

أفضل:

  • كل سيناريو ينشئ ما يحتاجه.
  • كل سيناريو ينظف بياناته إن أمكن.
  • القيم التي تنتقل بين الطلبات تكون داخل نفس السيناريو، مثل userId أو token.

اعزل البيئات

احتفظ ببيئات منفصلة:

  • local
  • CI
  • staging
  • production

واستخدم متغيرات مثل:

BASE_URL=https://api.staging.example.com
API_TOKEN=***
CUSTOMER_ID=c_123
Enter fullscreen mode Exit fullscreen mode

لا تكتب host أو secret مباشرة داخل الاختبار.

راجع بيئة الاختبار الافتراضية مقابل بيئة الاختبار.

الانتقال يساراً: الاختبار مبكراً

الانتقال يساراً يعني نقل الاختبار إلى وقت أبكر في دورة التطوير.

كلما اكتشفت الخطأ مبكراً، كان إصلاحه أرخص.

خطوات عملية

1. صمم العقد أولاً

اكتب مخططات الطلب والاستجابة قبل تنفيذ endpoint.

مثال مبسط:

{
  "type": "object",
  "required": ["id", "email"],
  "properties": {
    "id": { "type": "string" },
    "email": { "type": "string", "format": "email" }
  }
}
Enter fullscreen mode Exit fullscreen mode

من هذا العقد يمكنك توليد:

  • mocks
  • اختبارات schema
  • توثيق
  • سيناريوهات مبدئية

2. اختبر مقابل Mock قبل جاهزية backend

لا تجعل frontend أو فريق التكامل ينتظر endpoint الحقيقي.

استخدم mock server مبني من العقد حتى يبدأ المستهلكون مبكراً.

3. شغّل الفحوصات السريعة مع كل commit

الاختبارات الوظيفية والعقدية السريعة يجب أن تكون جزءاً من حلقة المطور اليومية، لا دفعة ليلية فقط.

راجع اختبار الانتقال يساراً في تطوير واجهة برمجة التطبيقات.

أتمتة الاختبارات في CI

الاستراتيجية لا تصبح حقيقية إلا عندما تعمل بدون تدخل يدوي.

خط CI جيد لاختبارات API يجب أن:

  1. يشغّل الاختبارات مع كل push.
  2. يمنع الدمج عند الفشل.
  3. ينشر تقريراً واضحاً.
  4. يستخدم أسراراً ومتغيرات بيئة بدلاً من hardcoding.

مثال GitHub Actions:

name: api-tests

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install dependencies
        run: npm ci

      - name: Run API tests
        run: npm test
        env:
          BASE_URL: ${{ secrets.BASE_URL }}
          API_TOKEN: ${{ secrets.API_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

النمط ثابت مهما كانت الأداة:

  • checkout للكود
  • إعداد runtime
  • تثبيت الاعتمادات
  • تشغيل الاختبارات
  • أي exit code غير صفري يفشل البناء
  • نشر التقرير

راجع كيفية أتمتة اختبارات API في CI/CD.

كيف تتناسب Apidog مع الاستراتيجية

الاستراتيجية لا تعتمد على أداة واحدة. يمكنك استخدام أدوات منفصلة للتصميم، الاختبار، mocking، والتوثيق. لكن المشكلة المعتادة هي الانجراف: المواصفات في مكان، الاختبارات في مكان، والـ mocks في مكان آخر.

يجمع Apidog هذه الأجزاء في مصدر واحد للحقيقة:

  • تصميم عقد API
  • كتابة سيناريوهات الاختبار
  • إنشاء mocks من نفس المخطط
  • نشر التوثيق
  • تشغيل المجموعات المحفوظة في CI

تشغيل اختبارات Apidog في CI

ثبّت Apidog CLI:

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

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

  • --access-token: للمصادقة. خزّنه كـ CI secret.
  • -t: معرف السيناريو أو المجلد أو المجموعة.
  • -e: معرف البيئة، مثل staging أو CI.
  • -r: نوع التقرير، مثل cli أو html أو json أو junit.

استخدم junit حتى يقرأ CI نتائج النجاح والفشل.

تشغيل مدفوع بالبيانات

مثال باستخدام ملف CSV:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioId> \
  -e <environmentId> \
  -d ./data/users.csv \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

يمكنك أيضاً استخدام:

  • --upload-report لرفع التقرير إلى السحابة.
  • --branch للتشغيل مقابل فرع معين.

ملاحظة مهمة: Apidog CLI يشغل سيناريوهات ومجموعات Apidog المحفوظة. لا يعوض أداة load testing مخصصة، لذلك استخدم أداة أداء منفصلة لطبقة التحميل في الهرم.

قائمة تحقق لبناء استراتيجية اختبار API

ابدأ بهذه القائمة بالترتيب:

  • [ ] رتّب نقاط النهاية حسب المخاطر وحجم المرور.
  • [ ] اكتب اختباراً وظيفياً إيجابياً لكل endpoint مهمة.
  • [ ] أضف اختباراً سلبياً واحداً على الأقل لكل endpoint.
  • [ ] أضف edge cases للمدخلات الرقمية والنصية والقوائم.
  • [ ] أضف اختبارات عقد لأي API يستهلكها فريق أو عميل آخر.
  • [ ] أضف اختبارات تكامل للتدفقات التي تعبر أكثر من خدمة.
  • [ ] استخدم بيئات منفصلة ومتغيرات لكل بيئة.
  • [ ] لا تضع الأسرار أو hosts داخل الاختبارات مباشرة.
  • [ ] استخدم بيانات اختبار منشأة أو مزروعة.
  • [ ] اجعل الاختبارات مستقلة وقابلة لإعادة التشغيل.
  • [ ] شغّل الاختبارات السريعة مع كل push في CI.
  • [ ] افشل البناء عند فشل أي assertion مهم.
  • [ ] شغّل الاختبارات البطيئة ليلاً أو قبل الإصدار.
  • [ ] انشر تقرير JUnit أو HTML.
  • [ ] راجع الاختبارات عند تغيير العقد أو حذف endpoint.

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

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

ما الفرق بين استراتيجية اختبار API وخطة الاختبار؟

الاستراتيجية هي النهج العام: أنواع الاختبارات، الطبقات، ومتى تعمل.

خطة الاختبار أكثر تحديداً لإصدار أو ميزة معينة: endpoints، الحالات، البيانات، ومعايير النجاح.

الاستراتيجية غالباً مستقرة. الخطة تتغير مع كل إصدار.

كم عدد الاختبارات التي يجب أن تكون في كل طبقة من الهرم؟

لا توجد نسبة ثابتة، لكن الشكل مهم:

  • معظم الاختبارات في الأسفل: سريعة وتركز على طلب واحد.
  • عدد أقل في الوسط: تكامل وعقود.
  • عدد قليل في الأعلى: end-to-end للمسارات الحرجة.

إذا كانت اختبارات end-to-end أكثر من اختبارات الطلب الواحد، فأعد التوازن.

هل أحتاج إلى اختبار عقد إذا كان لدي اختبارات وظيفية؟

نعم، إذا كان هناك مستهلكون آخرون لـ API.

الاختبار الوظيفي يتحقق من سلوك endpoint. اختبار العقد يتحقق من أن الواجهة لم تتغير بطريقة تكسر المستهلكين.

قد تستمر endpoint في العمل، لكنها تكسر التطبيقات التي تعتمد على شكل استجابة قديم.

كم مرة يجب تشغيل اختبارات التحميل؟

شغّلها:

  • قبل الإطلاق
  • قبل ارتفاع معروف في المرور
  • أسبوعياً أو شهرياً لاكتشاف التدهور
  • بعد تغييرات كبيرة في الأداء أو البنية

لا تشغلها مع كل commit لأنها بطيئة ومكلفة.

هل يمكن أتمتة الاستراتيجية بالكامل في CI؟

يمكن أتمتة الأجزاء القابلة للتكرار:

  • الاختبارات الوظيفية
  • اختبارات التكامل
  • اختبارات العقد
  • اختبارات الانحدار

أما اختبارات التحميل والأمان فقد تحتاج جداول منفصلة أو بنية مخصصة. مشغل headless مثل Apidog CLI يغطي جزء CI عبر تشغيل السيناريوهات المحفوظة مع كل push.

Top comments (0)