Tavern هو قطعة هندسية ذكية. يتكامل مع pytest، ويسمح لك بوصف اختبار واجهة برمجة التطبيقات (API) كملف YAML، ويشغل هذا الملف كما لو كان اختبار pytest عاديًا. تحصل على النظام البيئي الكامل لـ pytest مجانًا: التركيبات (fixtures)، والإضافات (plugins)، وعمليات التشغيل المتوازية مع pytest-xdist، والتغطية (coverage)، ونفس الأمر الذي يستخدمه فريق Python الخاص بك بالفعل. بالنسبة لفريق الواجهة الخلفية الذي يعيش في pytest، فإن كتابة ملف test_*.tavern.yaml إضافي بجانب اختبارات الوحدات يبدو أمرًا طبيعيًا.
تظهر الصعوبات بمجرد أن يكبر ملف YAML. فطلب واحد يرسل نصًا، ويحفظ رمزًا مميزًا، ويتحقق من بعض حقول الاستجابة يتحول إلى كتلة متداخلة من مفاتيح request، response، save، و verify_response_with التي يجب عليك عمل مسافة بادئة لها بدقة. تدفقات متعددة المراحل (تسجيل الدخول، إنشاء مورد، قراءته مرة أخرى، حذفه) تجمع تلك الكتل في ملف واحد طويل حيث قد تؤدي مسافة موضوعة بشكل خاطئ إلى كسر التحليل، ويعيش عقد API الذي يتحقق منه الاختبار في مكان آخر تمامًا: ملف Swagger، صفحة wiki، أو مجموعة Postman عفا عليها الزمن منذ أشهر.
ما يميز Tavern
نبدأ بالإيجابيات، لأن Tavern يستحقها.
يعتمد على pytest بدلاً من استبداله. Tavern هو إضافة لـ pytest. يمكنك تثبيته باستخدام pip install tavern، وضع ملف YAML في دليل الاختبار الخاص بك، وسيقوم pytest باكتشافه وتشغيله كأي اختبار آخر. هذا يعني أنك تحتفظ بكل عادات pytest التي يمتلكها فريقك بالفعل: -k للتصفية، -x للتوقف عند الفشل الأول، pytest-html للتقارير، pytest-xdist للتشغيل المتوازي، التركيبات (fixtures) للإعداد المشترك. لا يتغير أي شيء في مشغّلك. بالنسبة لشركة تعتمد على Python، هذه ميزة حقيقية، وقليل من أدوات اختبار API تتكامل بهذه السلاسة مع مجموعة موجودة.
ملف YAML وصفي وقابل للقراءة. من السهل جدًا مسح اختبار Tavern بسيط:
test_name: Get a single order
stages:
- name: Fetch order 1042
request:
url: https://api.shop.test/orders/1042
method: GET
response:
status_code: 200
json:
id: 1042
status: shipped
لا يوجد "رمز لاصق" (glue code)، ولا مكتبة تأكيد للاستيراد، ولا حاجة لكتابة إطار عمل للاختبار. الطلب والاستجابة المتوقعة يجلسان جنبًا إلى جنب. للتحقق من رمز حالة وبضعة حقول، هذا أسهل في القراءة من معادل Python الذي يستخدم requests بالإضافة إلى assert.
حفظ المتغيرات وتسلسلها. يمكن لـ Tavern سحب قيمة من استجابة واحدة وحقنها في المرحلة التالية باستخدام save واستبدال {variable}، لذا فإن تدفق تسجيل الدخول ثم الاتصال يعمل بدون رمز مخصص:
stages:
- name: Log in
request:
url: https://api.shop.test/auth/login
method: POST
json:
username: tester
password: hunter2
response:
status_code: 200
save:
json:
token: access_token
- name: Read the profile with the saved token
request:
url: https://api.shop.test/me
method: GET
headers:
Authorization: "Bearer {token}"
response:
status_code: 200
يفعل أكثر من HTTP. يختبر Tavern أيضًا MQTT، وهو أمر مهم إذا كنت تعمل مع إنترنت الأشياء (IoT) أو الأنظمة المعتمدة على الرسائل. ولأنه يعتمد على pytest، يمكنك خلط اختبارات API بـ YAML واختبارات Python العادية في نفس التشغيل ونفس التقرير.
لا شيء من هذا تسويق. Tavern أداة قوية. السؤال هو ما إذا كانت افتراضاته تتطابق مع افتراضاتك.
أين تتراكم تعقيدات YAML
تأتي ثلاثة تكاليف مجمعة مع نموذج Tavern، وما إذا كانت مهمة يعتمد على مدى كبر مجموعتك.
YAML حساس للمسافات البيضاء، والمخطط عميق. المثال البسيط أعلاه نظيف. الاختبار الواقعي ليس كذلك. بمجرد إضافة الرؤوس (headers)، ومعلمات الاستعلام (query parameters)، وجسم الطلب (request body)، وتأكيدات جسم الاستجابة (response-body assertions)، وفحوصات النوع (type checks)، والمتغيرات المحفوظة (saved variables)، ووظائف verify_response_with الخارجية، فإنك تتداخل أربعة أو خمسة مستويات عميقة في تنسيق حيث مسافة خاطئة واحدة هي خطأ في التحليل، وليست رسالة واضحة. لا تكمل المحررات مفاتيح Tavern تلقائيًا بالطريقة التي تكمل بها بيئة التطوير المتكاملة (IDE) طريقة Python، لذا فإنك تتحقق من المستندات لمعرفة ما إذا كانت status_code أو status، json أو body، لكل حقل جديد.
الاختبار وعقد API هما نتيجتان منفصلتان. يقوم ملف YAML الخاص بـ Tavern بتضمين عنوان URL والطريقة والحقول المتوقعة وأنواعها. يعيش تعريف API الفعلي في ملف OpenAPI، أو في مزخرفات المسار (route decorators) الخاصة بإطار عمل، أو لا أحد متأكد تمامًا من مكانه. عندما يغير API اسم حقل، لا شيء يخبر YAML. يستمر الاختبار في تأكيد الشكل القديم حتى يفشل في CI أو، الأسوأ من ذلك، يستمر في النجاح مقابل توقع قديم. يجب على شخص ما الحفاظ على تزامن الاثنين يدويًا، وهذا الشخص عادة ما يكون هو الذي يقع عليه عبء الفشل في الساعة 2 صباحًا.
يفترض وجود سلسلة أدوات Python وأشخاص Python. Tavern رائع إذا كان المختبرون لديك يكتبون بلغة Python. إذا كانت مجموعة ضمان الجودة (QA) الخاصة بك، أو مهندسو الواجهة الأمامية، أو موظفو المنتج يرغبون في إضافة أو قراءة اختبار، فإنهم يصطدمون بـ pip و virtualenvs واتفاقيات pytest وقواعد مخطط YAML دفعة واحدة لمجرد إرسال طلب HTTP والتحقق من الاستجابة. نقطة البداية شديدة الانحدار لأي شخص خارج عالم Python.
المسار لتجاوز YAML
البديل هو التوقف عن تأليف الاختبارات كملفات نصية والبدء في بنائها مقابل تعريف API الذي تمتلكه بالفعل.
في Apidog، مواصفات API والطلب والاختبار هي نفس الكائن. يمكنك استيراد أو تصميم API الخاص بك مرة واحدة (OpenAPI أو Swagger أو مجموعة Postman يتم استيرادها بنقرة واحدة)، وتحمل كل نقطة نهاية مخططها الحقيقي معها. يمكنك بناء سيناريو اختبار عن طريق ربط نقاط النهاية هذه بصريًا: اسحب مكالمة تسجيل الدخول، واسحب المكالمة التي تحتاج إلى الرمز المميز، ومرر القيمة إلى الأمام دون كتابة كتل save: أو سلاسل {variable} يدويًا. التأكيدات هي مربعات اختيار وتعبيرات في لوحة، وليست مفاتيح YAML ذات مسافات بادئة يجب عليك تذكرها.
نظرًا لأن الاختبار مبني على المواصفات، فإن المواصفات هي مصدر الحقيقة الوحيد. يؤدي تغيير حقل استجابة في التصميم إلى إظهار التغيير في سيناريوهات الاختبار التي تشير إليه بدلاً من الانجراف الصامت. هذا هو الجزء الذي لا يمكن لـ Tavern القيام به هيكليًا: ملف YAML الخاص به لا يحتوي على رابط يعود إلى العقد.
وعندما يحين وقت الأتمتة، فإنك لا تفقد خاصية التشغيل بدون واجهة رسومية والصديقة لـ CI التي جعلت Tavern جذابًا. يقوم Apidog CLI بتشغيل نفس السيناريوهات من سطر الأوامر، في CI، بدون واجهة رسومية، تمامًا بالطريقة التي يشغل بها pytest ملفات Tavern الخاصة بك اليوم.
تثبيت وتشغيل Apidog CLI
المشغّل هو حزمة npm مجانية تسمى apidog-cli. قم بتثبيتها عالميًا:
npm install -g apidog-cli
ثم قم بتشغيل سيناريو اختبار باستخدام الأمر apidog run:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli
إليك ما يفعله كل جزء:
--access-tokenيوثّق عملية التشغيل مقابل حساب Apidog الخاص بك. أنشئ الرمز المميز من علامة تبويب CI/CD للسيناريو وقم بتخزينه كسِرّ، وليس في الملف أبدًا.-tهو معرف سيناريو الاختبار.-eهو معرف البيئة (التطوير، التجهيز، الإنتاج)، بحيث يصل نفس السيناريو إلى عنوان URL الأساسي الصحيح والمتغيرات.-rيختار المُبلغين.cliيطبع مخرجات قابلة للقراءة إلى الطرفية.
لا يتعين عليك حفظ هذه المعرفات. افتح سيناريو الاختبار في Apidog، انتقل إلى علامة التبويب CI/CD الخاصة به، اختر خيار سطر الأوامر، وانقر على "Generate token". يقوم Apidog ببناء أمر apidog run بالكامل لك مع ملء معرف السيناريو ومعرف البيئة بالفعل. انسخه، ثم انقل الرمز المميز إلى سر CI.
إذا كنت تفضل عدم التثبيت عالميًا، خاصة على مشغّل CI سريع الزوال، فقم بتشغيله باستخدام npx:
npx apidog-cli run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli
تغطي المُبلغون cli و html و json و junit. بالنسبة لـ CI، التوليفة المفيدة هي -r html,junit: يخرج junit ملف XML القياسي الذي تفسره كل لوحة تحكم CI تقريبًا إلى شجرة نجاح/فشل، وينتج html تقريرًا قابلاً للتصفح يمكنك أرشفته كمنتج بناء. أضف --out-dir للتحكم في مكان هبوطها:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r html,junit --out-dir ./apidog-reports
للحصول على قائمة الأعلام الكاملة في نسختك المثبتة، قم بتشغيل apidog run --help.
جنباً إلى جنب
| Tavern | Apidog | |
|---|---|---|
| تنسيق الاختبار | ملفات YAML (*.tavern.yaml) |
سيناريوهات مرئية مبنية على المواصفات |
| وقت التشغيل | Python + pytest | apidog run بدون واجهة رسومية (حزمة npm) |
| التأليف/الإنشاء | كتابة YAML يدوياً مع المسافات البادئة | سحب وربط نقاط النهاية، تأكيدات عبر مربعات الاختيار |
| عقد API | محتوى منفصل، تتم مزامنته يدوياً | المواصفات هي مصدر الحقيقة للاختبار |
| سلسلة المتغيرات | كتل save: واستبدال {var} |
تمرير القيم بين الخطوات في الواجهة الرسومية |
| المُبلغون | pytest-html، JUnit عبر إضافات pytest |
cli، html، json، junit مدمجة |
| من يمكنه كتابة الاختبارات | المختبرون الملمون بلغة Python | أي شخص في الفريق، بمن فيهم غير المبرمجين |
| البروتوكولات | HTTP و MQTT | HTTP، بالإضافة إلى SOAP، WebSocket، gRPC، والمزيد |
يتفوق Tavern إذا كان فريقك يعتمد كليًا على Python وتريد أن تعيش الاختبارات في نفس المستودع ونفس تشغيل pytest مثل اختبارات وحدتك. ويتفوق Apidog إذا كنت ترغب في التخلص من صيانة YAML، والاحتفاظ بالعقد والاختبار كشيء واحد، والسماح للأشخاص الذين لا يكتبون Python بالمساهمة في الاختبارات.
ربطه بالاندماج المستمر (CI)
التشغيل بدون واجهة رسومية هو الهدف الأساسي من الانتقال من ملف اختبار محلي إلى خط أنابيب. إليك شكل إجراءات GitHub:
name: API tests
on: [push, pull_request]
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- name: Install Apidog CLI
run: npm install -g apidog-cli
- name: Run API test scenario
run: |
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t 605067 \
-e 1629989 \
-r html,junit \
--out-dir apidog-reports
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: apidog-report
path: apidog-reports
يأتي الرمز المميز من أسرار المستودع ويصل إلى الخطوة كمتغير بيئة. يعني if: always() في خطوة التحميل أنك لا تزال تحصل على التقرير عند فشل الاختبارات، وهذا هو بالضبط الوقت الذي تريد قراءته فيه. إذا فشل تأكيد ما، فإن خطوة apidog run تخرج برمز غير صفري، وتصبح المهمة حمراء، ويظهر طلب السحب فحصًا فاشلاً.
هذا السلوك الخاص برمز الخروج هو بوابة الجودة، ويعمل بنفس طريقة عمل Tavern: يقرأ CI رمز الخروج لكل خطوة، ويؤدي الخروج غير الصفري إلى فشل المهمة، وتمنع المهمة الفاشلة الدمج أو النشر. لا تحتاج إلى تكوين أي شيء إضافي. لإعدادات خطوط الأنابيب الأكثر تعمقًا، يغطي Apidog CLI في خط أنابيب CI/CD الخاص بك ودليل GitHub Actions أيضًا أنواع GitLab CI و Jenkins.
ملاحظة حول pytest وعالم اختبار Python الأوسع
الانتقال من YAML الخاص بـ Tavern لا يعني التخلي عن pytest. تحتفظ العديد من الفرق باختبارات الوحدة والتكامل الخاصة بـ Python البحتة في pytest وتستخدم Apidog لطبقة اختبار عقد API، الجزء الذي يجب أن يتتبع فيه الاختبار المواصفات ويتم تشغيله للمساهمين غير المتخصصين في Python أيضًا. الاثنان لا يستبعدان بعضهما البعض. كانت قيمة Tavern دائمًا في السماح لأشخاص pytest بكتابة اختبارات API بتنسيق أخف من رمز requests الخام؛ قيمة Apidog هي جعل اختبارات API هذه تتتبع العقد وتبقى قابلة للقراءة مع نمو المجموعة لتتجاوز عددًا قليلاً من الملفات.
إذا كنت تفكر أيضًا في مشغلات أخرى، فإن نفس المنطق ينطبق على قصة سطر الأوامر في Postman في مقارنة Postman CLI و Newman وعلى تشغيل المجموعات بدون أدوات إضافية في اختبار API بدون Postman.
الأسئلة الشائعة
هل Apidog CLI مجاني؟ نعم. حزمة npm apidog-cli مجانية للتثبيت والتشغيل باستخدام npm install -g apidog-cli. تقوم بتنفيذ سيناريوهات الاختبار من مشروع Apidog الخاص بك، لذا فإن ما يمكنك تشغيله يعتمد على خطة Apidog الخاصة بك، ولكن المشغل الذي يعمل بسطر الأوامر نفسه ليس منتجًا مدفوعًا منفصلاً.
هل لا يزال بإمكاني استخدام pytest جنبًا إلى جنب مع Apidog؟ نعم. احتفظ باختبارات الوحدات والتكامل لـ Python في pytest واستخدم Apidog لطبقة اختبار عقد API. العديد من الفرق تشغل الاثنين. الفرق هو أن اختبارات Apidog تتتبع المواصفات بدلاً من ترميزها بشكل ثابت في ملف منفصل.
كيف يمنع Apidog دمجًا سيئًا في CI؟ من خلال رمز الخروج. عندما يفشل أي تأكيد، يخرج apidog run برمز غير صفري. يقرأ CI رمز الخروج هذا، ويضع علامة على الخطوة بأنها فشلت، ويمنع الدمج أو النشر. لا تحتاج إلى تكوين أي شيء إضافي لكي يعمل هذا.
أي مُبلغ يجب أن أستخدمه لـ CI؟ استخدم junit للحصول على النتيجة القابلة للقراءة آليًا التي تفسرها لوحة تحكم CI الخاصة بك إلى شجرة نجاح/فشل، وأضف html إذا كنت تريد تقريرًا قابلاً للتصفح محفوظًا كمنتج بناء. الخيار الشائع هو -r html,junit، مع الاحتفاظ بـ cli لتوفير مخرجات سجل بناء قابلة للقراءة.
هل يختبر Apidog HTTP فقط، مثل وضع HTTP في Tavern؟ لا. يغطي Apidog HTTP بالإضافة إلى SOAP و WebSocket و Server-Sent Events و gRPC. يضيف Tavern MQTT إلى HTTP، وهذا هو المكان الوحيد الذي تتجاوز فيه تغطيته للبروتوكولات ما يوفره Apidog، لذا ضع ذلك في الاعتبار إذا كان MQTT مركزيًا في مكدسك.
الخلاصة الصادقة
Tavern هي طريقة نظيفة لكتابة اختبارات API إذا كنت تفكر بالفعل في pytest و YAML، وتكامل pytest هو بالفعل أفضل ميزة له. التكلفة هي YAML نفسه: ينمو عميقًا وهشًا مع توسع المجموعات، ولا يوجد لديه رابط يعود إلى عقد API الذي يتحقق منه. إذا كنت تريد نفس السلوك بدون واجهة رسومية، والفشل الواضح في CI دون كتابة مسافات بادئة لـ YAML يدويًا ودون الاحتفاظ بنسخة ثانية من مواصفاتك، فإن بناء الاختبارات مقابل العقد وتشغيلها باستخدام apidog run هو المسار الأخف.
قم بتنزيل Apidog واستورد واجهة برمجة تطبيقات موجودة لتجربة سير عمل "المواصفات هي الاختبار" قبل الالتزام. إنه مجاني للبدء.
