اختبار API / أساسي: ملاحظات واجهة موثوقة / الدرس 2
اختبار استجابات HTTP بوصفها عقودا منظمة
جمع الطريقة والحالة والترويسات والتمثيل وأثر الحالة في توقع متسق.
في هذه الصفحة
أهداف الدرس
- التمييز بين دلالات HTTP ونتيجة العمل الخاصة بالخدمة.
- توحيد أسماء الترويسات مع الحفاظ على القيم التي تهم بنيتها.
افحص أكثر من رقم الحالة
استجابة HTTP تجمع معلومات البروتوكول والتمثيل. يعيد البحث الناجح في الفهرس الخيالي تمثيل JSON ونوع وسائط معلنا ومعرف كتاب ثابتا. تخالف حالة 200 مع صفحة تسجيل دخول HTML هذا العقد رغم نجاح التبادل. تحتاج استجابة الإنشاء والاستجابة الخالية من الجسم إلى توقعات مختلفة. افصل قواعد البروتوكول عن اختيارات التطبيق: يحدد HTTP دلالات الطرق والحالات، وتحدد الواجهة حقول مواردها وسير العمل. اقرأ المصدرين قبل كتابة التأكيد.
توحيد الأسماء في الطبقة المناسبة
أسماء حقول الترويسات غير حساسة لحالة الأحرف. الاختبار الذي يقبل Content-Type ويرفض content-type يرتبط بتفصيل عرضي في النقل. وحّد الأسماء قبل البحث ثم حلل القيم حسب قواعدها. لا تحول الاستجابة كلها إلى أحرف صغيرة؛ فقد يكون معرف مبهم أو رمز حساسا لحالة الأحرف. تحتاج الحقول المكررة معالجة خاصة لأن قواعد الجمع تعتمد على الحقل. يستخدم النموذج قاموسا بقيمة واحدة لكل حقل، لذلك لا يختبر التكرار أو تحليل البيانات المنقولة.
headers = {"Content-Type": "application/json; charset=utf-8", "X-Case": "Book-A"}
normalized = {name.lower(): value for name, value in headers.items()}
media_type = normalized["content-type"].split(";", 1)[0].strip().lower()
assert media_type == "application/json"
assert normalized["x-case"] == "Book-A"
print("header contract accepted")
header contract accepted
يعالج المثال المحلي الكامل قيمة بسيطة لنوع الوسائط ومفاتيح فريدة فقط. يوضح حد التوحيد المختار. يجب أن يعالج محلل الإنتاج بنية الحقل الموثقة والقيم المكررة بصورة صحيحة.
افحص متى يسمح بالتمثيل
يجب أن تتبع التأكيدات الطريقة والحالة المختارتين. لا تحمل استجابة HEAD محتوى، مع أن البيانات الوصفية قد تصف تمثيل GET المقابل. كذلك لا تحمل استجابة 204 محتوى. المساعد الذي يحلل JSON دائما يحول الاستجابة الفارغة الصحيحة إلى خطأ فك ترميز ويحجب العقد الحقيقي. ابدأ بتحديد هل يتوقع محتوى، ثم افحص نوعه، ثم فك ترميزه وتحقق منه. المثال فحص قرار مختلق ولا ينشئ رسالة HTTP فعلية أو يستقبلها أو يحللها.
cases = [("GET", 200, b'{"id":"book-4"}'), ("HEAD", 200, b""), ("DELETE", 204, b"")]
for method, status, body in cases:
content_forbidden = method == "HEAD" or status == 204
if content_forbidden:
assert body == b""
else:
assert body.startswith(b"{")
print("three response cases accepted")
three response cases accepted
يفحص الفرع الأول شرط غياب المحتوى للحالات المذكورة. والفرع الآخر فحص أولي للبيانات فقط وليس تحقق JSON. هذه المصفوفة الصغيرة ليست تنفيذا شاملا لجميع قواعد استجابات HTTP.
ربط دلالة الطريقة بتوقعات الحالة
الطريقة الآمنة لا تطلب تغيير الحالة وفق دلالتها المحددة، لكنها لا تمنع آثارا عرضية مثل التسجيل. ويتعلق التماثل التكراري بالأثر المقصود للطلبات المتطابقة، لا بتطابق بايتات الاستجابة. حافظ على هذا الفرق في وصف الاختبار. في البحث افحص بقاء سجلات الفهرس المحمية دون تغيير، ولا تفشل لمجرد تغير عداد تدقيق مصرح به. وفي الحذف المتكرر اختر توقعات تتفق مع عقد المورد؛ فقد تختلف الاستجابة الثانية بينما تبقى الحالة النهائية المقصودة نفسها.
تحديد موضع اختلاف البروتوكول والعمل
عند فشل اختبار الاستجابة احتفظ بالطريقة وقالب المسار والحالة والترويسات غير السرية المختارة وملخص بنيوي منقح للجسم. لا تعتبر كل خطأ فك ترميز عيبا في العمل على الخادم؛ فقد اتبع العميل تحويلا أو افترض نوع محتوى خاطئا. قارن العقد عند كل حد قبل تغيير التأكيدات. استخدم مقارنة دقيقة للحقول الثابتة وسماحا صريحا للاختلاف الموثق. لا تقبل كل حالات 2xx أو كل أنواع الوسائط لمجرد إزالة الفشل، فذلك يضعف ما تثبته الحزمة.
الأخطاء الشائعة وإصلاحها
يفشل فك JSON لاستجابة 204 صحيحة
- لماذا يحدث؟
- يفترض مساعد مشترك أن كل نجاح يحمل محتوى.
- كيف تصلحه؟
- حدد توقع المحتوى قبل فك الترميز.
- كيف تتجنب تكراره؟
- غط العقود الفارغة وذات الجسم منفصلة.
يعتمد تأكيد الترويسة على حالة الأحرف
- لماذا يحدث؟
- يقارن الاختبار الكتابة بدلا من الدلالة.
- كيف تصلحه؟
- وحّد أسماء الحقول واحفظ القيم المهمة.
- كيف تتجنب تكراره؟
- استخدم محولا يراعي الحقول واختبر تكرارها.
تنجح أي حالة 2xx في اختبار الإنشاء
- لماذا يحدث؟
- يخفي نطاق الحالات الواسع تغير العقد.
- كيف تصلحه؟
- أكد حالة الإنشاء والتمثيل وأثر الحالة الموثقة.
- كيف تتجنب تكراره؟
- راجع تغير الحالات بوصفه تغيرا في العقد.
اختبر فهمك
1. لا يحمل HEAD جسما ويحمل Content-Type نفسه في GET. هل يلزم تحليل JSON؟
اعرض الحل المشروح
لا؛ ليس هناك محتوى لفك ترميزه. افحص البيانات الوصفية المناسبة وغياب المحتوى وفق العقد. لا تستنتج خطأ البيانات الوصفية بسبب غياب بايتات JSON. يحتاج السلوك المنقول إلى اختبار بروتوكولي مصرح به.
2. يعيد DELETE المتكرر 204 ثم 404. هل ينفي ذلك وحده التماثل التكراري؟
اعرض الحل المشروح
لا. قارن الحالة النهائية المقصودة: يبقى المورد غائبا بعد الطلبين. تطابق الاستجابة والأثر التكراري خاصيتان مختلفتان. أما توافق الحالتين مع عقد الخدمة فيحتاج إلى تأكيد موثق مستقل.
أهم ما تعلمته
- أكد عقدا متسقا للحالة والترويسات والتمثيل والحالة المخزنة.
- حلل المحتوى الذي تسمح به الطريقة والحالة فقط.
- وحّد أسماء الحقول دون إعادة كتابة البيانات المبهمة.