كيفية تشغيل اختبارات API المبارامترية من ملفات CSV و JSON

اختبار واجهات برمجة التطبيقات المُحدّد بمعايير يتيح لك تشغيل سيناريو واحد عبر المئات من حالات CSV أو JSON. قم ببنائه مرة واحدة في Apidog، وشغّله آليًا في CI.

INEZA Felin-Michel

INEZA Felin-Michel

16 يونيو 2026

كيفية تشغيل اختبارات API المبارامترية من ملفات CSV و JSON

enterprise.banner.title

enterprise.banner.feature1

enterprise.banner.feature2

enterprise.banner.feature3

enterprise.banner.ctaB

لقد كتبت اختبار تسجيل دخول. وقد نجح. ثم يسأل أحد أعضاء الفريق السؤال البديهي: هل ينجح لحساب مقفل، أو بريد إلكتروني غير متحقق منه، أو كلمة مرور بها مسافة زائدة في النهاية، أو سلسلة حقن SQL التي سيقوم أحدهم بلصقها في الحقل في النهاية؟ الآن لديك خيار. إما أن تنسخ هذا الاختبار خمس مرات وتغير قيمة واحدة في كل نسخة، أو أن تجد طريقة لتغذية نفس الاختبار بالعديد من صفوف الإدخال وتدعه يقوم بتشغيلها كلها.

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

زر

ماذا يعني الاختبار المبرمج بالفعل

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

تخيل سيناريو اختبار واحد لنقطة نهاية رمز الخصم. المنطق هو نفسه دائمًا. إرسال POST /api/orders مع رمز، ثم التأكيد على الاستجابة. تتغير البيانات حسب الحالة:

الرمز إجمالي الطلب الحالة المتوقعة الخصم المتوقع
WELCOME10 100 200 10
WELCOME10 5 422 0
EXPIRED 100 410 0
(فارغ) 100 400 0
FAKE123 100 404 0

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

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

لماذا يتفوق ملف البيانات المنفصل على القيم المكتوبة مباشرة

يمكنك تضمين كل حالة مباشرة في الاختبار. يبدأ معظم الناس من هنا. تظهر المشكلة لاحقًا.

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

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

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

إعداد ملف البيانات الخاص بك

ابدأ بـ CSV للحالات الجدولية. صف الرأس يسمي متغيراتك؛ كل صف أدناه هو تكرار واحد. إليك جدول رمز الخصم كملف حقيقي، discount-cases.csv:

code,order_total,expected_status,expected_discount
WELCOME10,100,200,10
WELCOME10,5,422,0
EXPIRED,100,410,0
,100,400,0
FAKE123,100,404,0

يصبح كل رأس عمود متغيرًا تشير إليه داخل الاختبار. في نص الطلب، تكتب {{code}} و {{order_total}}؛ في التأكيدات، تقارنها بـ {{expected_status}} و {{expected_discount}}. يقوم المشغّل بالربط صفًا بصف.

عندما تكون مدخلاتك متداخلة، استخدم JSON. تسمح مصفوفة من الكائنات، كائن واحد لكل تكرار، لكل حالة بحمل بيانات منظمة قد يكون من الصعب تسطيحها في أعمدة. إليك user-cases.json لنقطة نهاية إنشاء مستخدم حيث تحتوي الحمولة على حقول متداخلة:

[
  {
    "scenario": "valid full profile",
    "user": {
      "email": "ada@example.com",
      "roles": ["admin", "billing"],
      "profile": { "country": "US", "timezone": "America/New_York" }
    },
    "expected_status": 201
  },
  {
    "scenario": "missing email",
    "user": {
      "email": "",
      "roles": ["viewer"],
      "profile": { "country": "GB", "timezone": "Europe/London" }
    },
    "expected_status": 400
  },
  {
    "scenario": "unknown role",
    "user": {
      "email": "grace@example.com",
      "roles": ["wizard"],
      "profile": { "country": "CA", "timezone": "America/Toronto" }
    },
    "expected_status": 422
  }
]

داخل الاختبار، تشير إلى القيم المنظمة بنفس صيغة {{user}}، {{expected_status}}، ويسلم Apidog حقول كل كائن للتكرار. عمود scenario هو تسمية لك؛ يظهر في التقرير بحيث تقرأ التكرار الفاشل "دور غير معروف" بدلاً من "التكرار 3".

تساعد بعض القواعد في تجنب المشاكل مع ملفات البيانات:

بناء السيناريو المبرمج في Apidog

في تطبيق Apidog، قم بإنشاء سيناريو الاختبار مرة واحدة كأي سيناريو آخر. أضف الطلب إلى نقطة النهاية الخاصة بك. في النص الأساسي، استبدل القيم الحرفية بمراجع المتغيرات: {{code}}، {{order_total}}، وهكذا. هذه هي الأعمدة من ملف البيانات الخاص بك.

ثم أضف التأكيدات التي تقرأ من نفس الملف. على سبيل المثال الخصم، ستؤكد أن حالة الاستجابة تساوي {{expected_status}} وأن حقل الخصم في نص JSON يساوي {{expected_discount}}. نظرًا لأن كل من المدخلات والمخرجات المتوقعة تأتي من الصف، فإن نفس منطق التأكيد يتحقق من صحة كل حالة بشكل صحيح. إذا لم تكن قد كتبت تأكيدات في Apidog من قبل، فإن تأكيدات API: دليل عملي يغطي الأنماط، وكيفية تعيين التأكيدات واستخراج المتغيرات من استجابة JSON يوضح جانب JSONPath بالتفصيل.

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

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

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

التطبيق هو المكان الذي تقوم فيه بالبناء وتصحيح الأخطاء. التكامل المستمر (CI) هو المكان الذي يثبت فيه الاختبار جدارته، حيث يتم تشغيله مع كل طلب سحب دون الحاجة إلى نقرة زر من أحد. هذا التسليم هو ما تهدف إليه واجهة سطر الأوامر Apidog CLI. إنها تأخذ السيناريو الذي قمت ببنائه في التطبيق وتشغله بدون واجهة مستخدم من طرفية، بنفس بيانات التكرار.

يتم شحن CLI كحزمة npm. قم بتثبيتها عالميًا:

npm install -g apidog-cli

الملف التنفيذي هو apidog، لذلك يبدأ كل أمر بـ apidog run. يشير التشغيل الأساسي إلى سيناريو بواسطة المعرف وبيئة بواسطة المعرف:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli

لتشغيل هذا السيناريو من ملف بيانات، أضف علامة iteration-data. تقبل مسارًا لملف JSON أو CSV:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 \
  -d ./discount-cases.csv -r cli,junit --out-dir ./test-reports

العلامة -d (الشكل الطويل --iteration-data) هي جوهر التشغيل المبرمج من سطر الأوامر. يقرأ Apidog الملف، ويشغل السيناريو مرة واحدة لكل صف، ويبلغ عن كل تكرار. استبدل discount-cases.csv بـ user-cases.json وتتعامل نفس العلامة مع مصفوفة JSON؛ يلتقط المشغّل التنسيق من الملف. تعامل مع رمز الوصول ككلمة مرور وخزنه كسر CI، ولا تضعه أبدًا في ملف ملتزم به. لهذا السبب، يشير كل مثال إلى $APIDOG_ACCESS_TOKEN بدلاً من قيمة حرفية.

تتزامن بعض العلامات بشكل طبيعي مع التشغيلات المبرمجة:

إذا كنت تريد القائمة الموثوقة والحالية للعلامات لإصدارك المثبت، فقم بتشغيل apidog run --help. تطبع واجهة سطر الأوامر كل خيار بشكله القصير والطويل.

ربط التشغيلات المبرمجة بالتكامل المستمر (CI)

السبب للاستثمار في الاختبارات المبرمجة هو أنها تؤتي ثمارها تلقائيًا. إليك مهمة GitHub Actions تقوم بتثبيت واجهة سطر الأوامر وتشغيل سيناريو موجه بملف CSV عند كل طلب سحب:

name: API tests
on: [pull_request]

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install Apidog CLI
        run: npm install -g apidog-cli
      - name: Run parameterized API tests
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
        run: |
          apidog run --access-token $APIDOG_ACCESS_TOKEN \
            -t 605067 -e 1629989 \
            -d ./tests/discount-cases.csv \
            -r cli,junit --out-dir ./test-reports
      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: api-test-report
          path: ./test-reports

يأتي الرمز المميز من secrets.APIDOG_ACCESS_TOKEN، والذي يتم تعيينه مرة واحدة في إعدادات المستودع الخاص بك. يكتب مراسل junit ملف XML تحوله معظم لوحات تحكم CI إلى شجرة نتائج لكل تكرار، لذلك يظهر الصف الفاشل كاختبار فاشل مُسمى بدلاً من جدار من نصوص السجل. تعني if: always() في خطوة التحميل أنك تحتفظ بالتقرير حتى عندما يفشل التشغيل، وهو بالضبط ما تريده في هذه الحالة. للحصول على تفاصيل أعمق حول جانب الإجراءات، راجع كيفية أتمتة اختبارات API في GitHub Actions.

يعمل نفس السيناريو ونفس ملف البيانات في أي نظام تكامل مستمر (CI). تختزل أنظمة GitLab CI و Jenkins و CircleCI والبقية كلها إلى نفس الحركات الثلاث: تثبيت Node و CLI، كشف الرمز المميز كمتغير بيئة، استدعاء apidog run مع -d. لا يوجد إعادة كتابة لاختباراتك لكل منصة.

مقارنة أساليب الاختبار المبرمج

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

يدعم Postman ومشغلوه ملفات البيانات أيضًا. باستخدام Collection Runner من Postman أو أداة سطر الأوامر Newman، يمكنك إرفاق ملف CSV أو JSON والإشارة إلى متغيرات {{column}} في الطلبات، تمامًا مثل النمط هنا. إنه نهج فعال وموثق جيدًا. المقايضة هي أن منطق الاختبار الخاص بك يعيش في JavaScript في نصوص ما قبل الطلب والاختبار، لذا مع تزايد تأكيداتك، فإنك تحتفظ بمزيد من التعليمات البرمجية. إذا كنت توازن بين مشغلات سطر الأوامر على وجه التحديد، فإن مقارنة بين Postman CLI و Newman توضح الفروقات.

توفر الأطر التي تعتمد على الكود أولاً مثل pytest مع @pytest.mark.parametrize، أو JUnit's @ParameterizedTest، أو REST Assured تحكمًا كاملاً بلغة البرمجة. إنها الخيار الصحيح عندما يحتاج منطق الاختبار الخاص بك إلى الكود بالفعل: إعداد معقد، توليد بيانات مخصص، ارتباط وثيق بقاعدة كود اختبار موجودة. التكلفة هي أن كل حالة تعيش في الكود، لذلك لا يمكن لغير المهندسين المساهمة، وعليك صيانة أنابيب HTTP بنفسك.

زاوية Apidog هي أن السيناريو مرئي والبيانات خارجية، لذلك يظل المنطق قابلاً للقراءة وتبقى الحالات مفتوحة لأي شخص يمكنه تعديل جدول بيانات، بينما لا يزال نفس السيناريو يعمل بدون واجهة مستخدم في التكامل المستمر (CI). إذا كنت تختار أداة محددة للتشغيلات الموجهة بالبيانات باستخدام CSV و JSON، فإن المقارنة في أي أداة لاختبار API الموجه بالبيانات باستخدام CSV أو JSON تتعمق في المفاضلات. لا يوجد خطأ في أي من هذه الطرق. قم بمطابقة النهج مع من يكتب الحالات ومقدار المنطق المخصص الذي تحتاجه كل حالة.

سير عمل عملي قابل للتطوير

إليك كيف يبدو هذا بمجرد أن يصبح جزءًا من روتين فريقك.

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

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

أخيرًا، قم بأتمتتها. ضع أمر apidog run -d في نظام التكامل المستمر (CI) بحيث يتم تشغيل الجدول بأكمله عند كل طلب سحب. الآن، أي تغيير يعطل مسار الرمز المنتهي الصلاحية سيفشل البناء لحظة دفعه، مع تكرار مُسمى يشير مباشرة إلى الصف المعطّل.

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

الأسئلة المتكررة

ما الفرق بين الاختبار المبرمج (Parameterized testing) والاختبار الموجه بالبيانات (Data-driven testing)؟ يصفان نفس الفكرة ويستخدم الناس المصطلحين بالتبادل. كلاهما يعني تشغيل اختبار واحد بشكل متكرر بمدخلات مختلفة ومخرجات متوقعة يتم توفيرها من خارج الاختبار. "المبرمج" يعتمد على آلية ربط المعلمات؛ "الموجه بالبيانات" يعتمد على مصدر البيانات الخارجي. عمليًا، تعامل معهما كمترادفين.

هل يجب علي استخدام CSV أم JSON لملف البيانات الخاص بي؟ طابق التنسيق مع شكل بياناتك. الحالات المسطحة والجداولية حيث يحتوي كل صف على نفس الأعمدة البسيطة تناسب CSV، وملف CSV أسهل لغير المهندسين لتعديله في جدول بيانات. أما حمولات البيانات المتداخلة أو المنظمة، مثل نص طلب يحتوي على مصفوفات وكائنات فرعية، فتتناسب مع JSON. يقرأ Apidog كلا التنسيقين كبيانات تكرارية، لذا اختر أيهما يمثل حالاتك دون تعقيد.

هل ستبطئ مئات التكرارات خط أنابيبي؟ كل صف هو تشغيل واحد للسيناريو، لذلك يتناسب الوقت الإجمالي مع عدد الصفوف مضروبًا في زمن استجابة كل طلب. بالنسبة لمعظم اختبارات API، يكون هذا الأمر ثوانٍ، وليس دقائق. إذا كان حجم البيانات الكبير يطيل وقت البناء الخاص بك، فقم بتقسيمه: قم بتشغيل مجموعة فرعية سريعة (smoke subset) عند كل طلب سحب، والجدول الكامل في مهمة ليلية أو قبل الإصدار. يعمل نفس السيناريو والملف على كليهما؛ يتغير فقط جزء البيانات.

كيف أحافظ على الأسرار بعيدًا عن ملفات البيانات وتكوين الاختبار الخاص بي؟ أبقِ بيانات الاعتماد خارج ملف البيانات تمامًا. يجب أن تكون الرموز المميزة وكلمات المرور في متغيرات البيئة أو في مخزن الأسرار الخاص بنظام التكامل المستمر (CI)، ويُشار إليها بـ $APIDOG_ACCESS_TOKEN وما شابه ذلك. يجب أن يحتوي ملف البيانات على مدخلات الاختبار والنتائج المتوقعة، وليس مواد المصادقة. يمكن لأي شخص يقرأ المستودع قراءة ملف CSV، لذا تعامل معه بهذه الطريقة.

هل يمكنني تشغيل نفس السيناريو المبرمج على بيئة التطوير (staging) والإنتاج؟ نعم. حافظ على السيناريو وملف البيانات ثابتين، وقم بتبديل البيئات باستخدام العلامة -e. وجه فحص طلب السحب (pull-request check) إلى بيئة التطوير واختبار سريع بعد النشر (post-deploy smoke test) إلى بيئة الإنتاج باستخدام نفس معرف السيناريو ونفس البيانات، ولكن بمعرف بيئة مختلف. هذا هو السبب الأساسي لكون البيئة والبيانات مدخلات منفصلة.

الخلاصة

يحول اختبار API المبرمج التغطية من مهمة نسخ ولصق روتينية إلى مهمة إدخال بيانات. تكتب الاختبار مرة واحدة، وتصف كل حالة كصف في ملف CSV أو JSON، وتدع المشغّل يقوم بالباقي. يظل المنطق صغيرًا وقابلًا للقراءة، وتبقى الحالات مفتوحة لأي شخص في الفريق، ويقوم التكامل المستمر (CI) بتشغيل الجدول بأكمله عند كل تغيير.

يوفر Apidog لك أداة بناء السيناريوهات المرئية للتأليف، وملفات CSV و JSON الخارجية للبيانات، وأمر apidog run -d للتنفيذ بدون واجهة رسومية في أي نظام CI. قم ببناء سيناريو واحد، ووجهه إلى جدول متزايد من الحالات، وستتسع تغطية اختبارك في كل مرة يضيف فيها شخص ما صفًا. قم بتنزيل Apidog وحوّل اختبارك الفردي المتقطع التالي إلى سيناريو مبرمج قابل للتطوير.

زر

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات