يبدأ اختبار REST API بدلالات رموز الحالة
يُسنِد REST معنى محددًا لرموز الحالة، وتعتمد التطبيقات العميلة على هذا المعنى. يجدر التحقق منه صراحةً بدلًا من افتراضه.
201 مع عنوان الموقع عند الإنشاء، لا 200 مع جسم استجابة ولا شيء غير ذلك.
404 لغير الموجود، و403 للممنوع. إرجاع 404 في حالة المنع خيارٌ متعمَّد تتخذه بعض الفرق، أما إرجاع 403 لمورد غير موجود فمجرد خلل.
422 أو 400 للمدخلات غير الصالحة، على نحوٍ متّسق. اختر أحدهما وتحقّق من التزام كل نقطة نهاية به.
لا 200 أبدًا مع خطأ داخل جسم الاستجابة. أمر شائع، ويُجبر كل تطبيق عميل على كتابة معالجة خاصة.
التماثل عند التكرار (Idempotency)
يُفترض أن يكون PUT وDELETE متماثلَي الأثر عند التكرار. فاستدعاؤهما مرتين ينبغي أن يُبقي الحالة نفسها دون أن يُنتج خطأً في المرة الثانية. من السهل الإخفاق في ذلك، ومن السهل التحقق منه: استدعِ العملية مرتين ثم تحقّق.
وينطبق الأمر نفسه على DELETE ثانٍ يُرجع 404 لا 500. فالتطبيقات العميلة تعيد المحاولة، ونقطة نهاية غير آمنة لإعادة المحاولة تُحوّل انقطاعًا شبكيًا عابرًا إلى عطل يراه المستخدم.
الأعراف التي تزعم خدمتك اتباعها
| ترقيم الصفحات | هل يُرجع المرور الكامل على النتائج العدد الذي تُعلنه المجموعة؟ فالخطأ بمقدار عنصر واحد عند حدود الصفحات شائع للغاية. |
| التصفية والترتيب | هل يُرفَض المرشِّح غير المعروف أم يُتجاهَل بصمت؟ التجاهل الصامت يُرجع بيانات خاطئة بثقة. |
| التحديث الجزئي | هل يغيّر PATCH ما أُرسِل فقط، أم يضبط الباقي على null بصمت؟ |
الفحص الكامن وراءها جميعًا
تحقّق من جسم الاستجابة، لا من رمز الحالة وحده. فاستجابة 200 بقائمة فارغة في موضع يُفترض أن يحوي سجلًا تجتاز كل تحقُّق من الحالة كُتب يومًا. هذه العادة وحدها تكشف من العيوب الحقيقية في اختبار REST API أكثر مما يكشفه أي فحص للأعراف.
المشكلات الأربع
أربعة أمور تحدّد ما إذا كانت مجموعة اختبارات API ستصمد عامها الأول: الجلسات التي تنتهي صلاحيتها، والقيم التي لا توجد إلا وقت التشغيل، والاستدعاءات التي يعتمد بعضها على بعض، والسجلات التي لا ينظّفها أحد. تعالج TestSprite هذه الأمور عبر Auto-Authentication وDynamic Variables وDependency Chains وAuto-Cleanup، الموصوفة في توثيق اختبار API.
الأعراف الجديرة بالتدوين أولًا
قبل اختبار ما إذا كانت واجهة API لديك تتبع أعرافها، لا بد أن يحدّد أحدهم ماهية هذه الأعراف، ومعظم الفرق تكتشف خلال هذا التمرين أنها غير متفقة عليها.
أربعة أسئلة تحسم معظم الأمر. ما رمز الحالة الذي تُرجعه عملية الإنشاء، وهل يتضمن عنوان الموقع؟ وهل المورد غير الموجود يُقابَل بـ404 أم بـ403 حين لا يكون مسموحًا للمستدعي برؤيته في الحالتين؟ وهل يُرفَض معامل الاستعلام غير المعروف أم يُتجاهَل؟ وهل يعامل PATCH الحقل الغائب على أنه دون تغيير أم على أنه null؟
لا يوجد لأيٍّ منها جواب صحيح على إطلاقه، وكلها خيارات تعتمد عليها التطبيقات العميلة. وتدوين الإجابات الأربع يستغرق عشرين دقيقة، ويحوّل نيةً غامضة في الالتزام بأسلوب REST إلى شيء يمكنك التحقق منه فعليًا، وهو الشرط المسبق لاختبار أيٍّ من ذلك.
الحصول على التغطية دون كتابتها كلها
تغطي الخطط المُولَّدة فئات الاختبار الوظيفي والمخطط والتصريح ومعالجة الأخطاء والحدود، انطلاقًا من مواصفة أو من جولة اكتشاف، وهو ما يشمل افتراضيًا معظم فحوص الأعراف المذكورة أعلاه.
الطرفية
npm install -g @testsprite/testsprite-cli
testsprite setup
إن كنت تفضّل ألا تثبّت شيئًا، فلوحة التحكم تؤدي الغرض نفسه. وكل ما يستطيع سطر الأوامر فعله غير ذلك تجده في مستودع CLI.
إن كان خط المعالجة مملوكًا لفريق آخر، فإن GitHub App هو المسار الأقل مقاومة: فهو webhook لا يغيّر شيئًا في مستودعك، ويُطلَق حين تُبلِّغ عملية البناء لديك بأن الإصدار الجديد صار مباشرًا. وإن أردت أن يكون الفحص ظاهرًا داخل المستودع بدلًا من ذلك، فإن خطوة GitHub Actions تؤدي هذا الغرض.
كيف تفحص TestSprite هذه الأعراف
تغطي الخطط المُولَّدة فئات الاختبار الوظيفي والمخطط والتصريح ومعالجة الأخطاء والحدود في مواجهة الخدمة العاملة، وهو ما يشمل معظم فحوص الأعراف أعلاه: دلالات رموز الحالة لكل عملية، ورفض المدخلات الخاطئة، والسلوك عند غياب المورد، وترقيم صفحات تتطابق أعداده.
يُبقي Auto-Authentication الجلسات حيّة طوال التشغيل، وتنقل Dynamic Variables القيم بين الاستدعاءات، وتشتقّ Dependency Chains ترتيب التنفيذ مما تحتاجه كل حالة وما تنتجه، ويزيل Auto-Cleanup ما أنشأه التشغيل بالضبط. والأخير أهمّ لـREST مما يتوقع الناس، لأن فحوص التماثل عند التكرار تعني استدعاء العملية التدميرية نفسها مرتين عن قصد.
والنتيجة أن أعرافك الخاصة يجري التحقق منها مع كل تغيير بدل أن تبقى موثَّقة ومرجوّة فحسب، وهذا ما يمنع نقطة نهاية واحدة من أن تُرجع 200 بصمت حيث تُرجع كل النقاط الأخرى 201.
هل يهمّ نقاء REST في الاختبار؟
فقط حيث تعتمد عليه التطبيقات العميلة. اختبر الأعراف التي تزعم خدمتك اتباعها، لا تلك التي يفرضها كتاب دراسي.
كيف نختبر HATEOAS؟
إن كنت تُرجع روابط، فتحقّق من أنها تُحَلّ فعلًا وتشير إلى ما تدّعيه. وإن لم تكن تفعل، فتجاوز الأمر؛ فقليل جدًا من الخدمات تطبّقه فعليًا.
ماذا عن GraphQL؟
أعراف مختلفة تمامًا. فرموز الحالة تحمل معنى أقل بكثير، والأخطاء تصل في جسم الاستجابة بحكم التصميم، ولذلك فإن الفحوص أعلاه لا تنتقل إليه في معظمها.
هل ينبغي أن نفحص ترويسات الاستجابة؟
نوع المحتوى دائمًا. وترويسات التخزين المؤقت وحدود المعدل إن كانت التطبيقات العميلة تتصرف بناءً عليها، وهو أمر يجدر معرفته قبل التحقق منها.
هل يستحق ترقيم الإصدارات الاختبار؟
نعم، إن كنت تدعم أكثر من إصدار. تحقّق من أن الإصدار القديم ما زال يتصرف كما كان، لأن هذا هو الوعد الذي يقطعه رقم الإصدار.
اختبر الوعود التي تقطعها واجهة API لديك.
ينبغي أن يتحقق اختبار REST API من الأعراف التي تزعم خدمتك اتباعها: دلالات رموز الحالة، والتماثل عند التكرار، وإجماليات ترقيم الصفحات، وما إذا كانت المرشِّحات غير المعروفة تُرفَض. وتحت هذه جميعًا، تحقّق من جسم الاستجابة لا من رمز الحالة.