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

لماذا تَتسرب تغييرات واجهات الـ API المسببة للكسر إلى الإصدارات؟
معظم الفرق ينتهي بها الأمر إلى وجود API واحد يخدم عدة عملاء: تطبيق ويب، تطبيق iOS، تطبيق Android، وأحياناً أدوات داخلية أيضاً. حتى لو اتفق الجميع على نفس النقاط النهائية، كل عميل يعتمد على الـ API بطرق مختلفة قليلاً. قد يتوقع أحد الشاشات وجود حقل دائماً، بينما يستخدمه شاشة أخرى فقط عند تطبيق فلتر.
تظهر المشكلة الحقيقية عندما تُنشر هذه الأجزاء على جداول زمنية مختلفة. قد يتغير جانب الخادم عدة مرات في اليوم، وتطرح تطبيقات الويب بسرعة، بينما تتحرك نُسخ الموبايل ببطء أكثر بسبب عمليات المراجعة والنشر المتدرج. هذا الفارق يخلق حالات كسر مفاجئة: يتم تحديث الـ API لأجل أحدث عميل، لكن نسخة الموبايل المنشورة بالأمس ما زالت في التداول وتتلقى استجابات لا تستطيع التعامل معها.
عندما يحدث ذلك، تكون الأعراض نادرة ما تكون خفية:
- شاشة تصبح فجأة فارغة لأن حقل تم إعادة تسميته أو نقله
- انهيارات (crashes) بسبب قيم null غير المتوقعة أو كائنات مفقودة
- تذاكر دعم "شيء ما معطل" مع خطوات يصعب إعادة إنتاجها
- ارتفاع في سجلات الأخطاء مباشرة بعد نشر الخادم
- إصدارات تصحيح عاجلة تضيف كود دفاعي بدل إصلاح السبب الجذري
الاختبار اليدوي وضمان الجودة غالباً ما يفشلان في كشف هذه المشاكل لأن الحالات الخطرة ليست مسار السعادة. قد يتحقق المختبر من أن "إنشاء طلب" يعمل، لكنه لا يجرب نسخة تطبيق أقدم، أو ملف تعريف معبأ جزئياً، أو دور مستخدم نادر، أو استجابة تحتوي على قائمة فارغة. أضف التخزين المؤقت، وfeature flags، والنشرات التدريجية، وستحصل على مجموعات أكثر مما يمكن لخطة اختبار أن تغطيه.
مثال شائع: يستبدل الخادم status: "approved" بـ status: { code: "approved" } لدعم الترجمة. يتم تحديث تطبيق الويب في نفس اليوم ويعمل جيداً. لكن نسخة iOS الحالية لا تزال تتوقع سلسلة نصية، تفشل في تحليل الاستجابة، ويرى المستخدمون صفحة فارغة بعد تسجيل الدخول.
لهذا السبب وُجد اختبار العقود لواجهات الـ API: ليس ليحل محل الـ QA، بل ليلتقط هذه التغييرات من فئة "يعمل مع أحدث عميل لدي" قبل أن تصل إلى الإنتاج.
ما هو اختبار العقود (وماذا ليس كذلك)
اختبار العقود هو طريقة يتفق فيها مستهلك الـ API (تطبيق ويب، تطبيق موبايل، أو خدمة أخرى) ومزود الـ API (الجهة الخلفية) على كيفية التحدث مع بعضهما. ذلك الاتفاق هو العقد. يختبر اختبار العقد شيئاً بسيطاً: هل لا يزال المزود يتصرف كما يعتمد المستهلك، حتى بعد التغييرات؟
عملياً، يقع اختبار العقود بين اختبارات الوحدة والاختبارات الشاملة (end-to-end). اختبارات الوحدة سريعة ومحلية، لكنها قد تفشل في كشف عدم التطابق بين الفرق لأنها تختبر كود داخلي، لا الحدود المشتركة. الاختبارات الشاملة تختبر مسارات حقيقية عبر أنظمة متعددة، لكنها أبطأ، أصعب صيانة، وغالباً ما تفشل لأسباب لا علاقة لها بتغيير API (بيانات الاختبار، توقيت واجهة المستخدم، بيئات متقلبة).
العقد ليس مستنداً ضخماً. إنه وصف مركز للطلبات التي سيرسلها المستهلك والاستجابات التي يجب أن يحصل عليها. عادةً يغطي العقد جيداً:
- النقاط النهائية والأساليب (مثال: POST /orders)
- الحقول المطلوبة والاختيارية، بما في ذلك الأنواع وقواعد أساسية
- رموز الحالة وشكل استجابات الأخطاء (كيف يبدو 400 مقابل 404)
- رؤوس الطلب وتوقعات المصادقة (وجود توكن، نوع المحتوى)
- القيم الافتراضية وقواعد التوافق الهامة (ماذا يحدث إذا غاب حقل)
هنا مثال بسيط على نوع الكسر الذي يكتشفه اختبار العقد مبكراً: يعيد الخادم total_price باسم totalPrice. قد تظل اختبارات الوحدة تمرّ. قد لا تغطي الاختبارات الشاملة تلك الشاشة أو تفشل لاحقاً بطريقة مربكة. يفشل اختبار العقد فوراً ويشير إلى عدم التطابق الدقيق.
من المفيد التوضيح ما ليس اختبار العقود: ليس بديل لاختبارات الأداء أو الأمان أو اختبار رحلة المستخدم الكاملة. كما أنه لن يكتشف كل خطأ منطقي. ما يقوم به هو تقليل المخاطر الأكثر شيوعاً في الفرق السريعة: تغييرات "صغيرة" في API تكسر العميل بصمت.
إذا كان جانب الخادم لديك مولَّداً أو يتغير كثيراً (مثلاً عند إعادة توليد APIs في منصة مثل AppMaster)، فإن اختبارات العقود شبكة أمان عملية لأنها تتحقق من أن توقعات العملاء لا تزال صحيحة بعد كل تغيير.
اختر نهج العقد لفرق الويب والموبايل
عندما تسلم فرق الويب والموبايل بشكل متكرر، الجزء الصعب ليس "اختبار الـ API" بحد ذاته، بل الاتفاق على ما يجب ألّا يتغير لكل عميل. هذا ما يساعد فيه اختبار العقود، لكنك لا تزال بحاجة لاختيار من يملك العقد.
الخيار 1: العقود المدفوعة بالمستهلك (Consumer-driven contracts - CDCs)
مع العقود المدفوعة بالمستهلك، يحدد كل عميل (تطبيق الويب، iOS، Android، تكامل شريك) ما يحتاجه من الـ API. بعدها يثبت المزود أنه قادر على تلبية تلك التوقعات.
هذا النهج يعمل جيداً عندما تتحرك العملاء بشكل مستقل، لأن العقد يعكس الاستخدام الفعلي، لا ما يظن فريق الخادم أنه مستخدم. كما أنه يتناسب مع واقع تعدد العملاء: قد يعتمد iOS على حقل لا يستخدمه الويب، وقد يهم الويب قواعد الترتيب أو التصفية التي يتجاهلها الموبايل.
مثال بسيط: يعتمد تطبيق الموبايل على أن price_cents عدد صحيح. الويب يعرض السعر فقط منسقاً، لذلك لن يلاحظ إذا حول الخادم الحقل إلى سلسلة نصية. عقد CDC من الموبايل سيكتشف هذا التغيير قبل النشر.
الخيار 2: مخططات يملكها المزود
مع مخطط يملكه المزود، ينشر فريق الخادم عقداً واحداً (غالباً مخطط أو مواصفة) ويطبقه. يختبر المستهلكون ضد مصدر الحقيقة هذا.
هذا مناسب عندما يكون الـ API عاماً أو مشتركاً عبر عملاء عديدة لا تملكهم، أو عندما تحتاج إلى اتساق صارم عبر الفرق. كما أنه أبسط للبدء: عقد واحد، مكان واحد لمراجعة التغييرات، ومسار موافقة واحد.
إليك طريقة سريعة للاختيار:
- اختر CDCs عندما تسلم العملاء كثيراً ويستخدمون أجزاء مختلفة من الـ API.
- اختر مخطط يملكه المزود عندما تحتاج إلى عقد "رسمي" واحد ومستقر للجميع.
- استخدم هجيناً عندما تستطيع: مخطط مزود كأساس، إضافة CDCs للنقاط النهائية عالية المخاطر.
إذا كنت تبني على منصة مثل AppMaster، نفس الفكرة تنطبق: اعتبر تطبيقات الويب والموبايل كمستهلكين منفصلين. حتى عند مشاركة الخلفية، نادراً ما تعتمد التطبيقات على نفس الحقول والقواعد تماماً.
ماذا تضع في عقد الـ API ليكتشف كسرًا حقيقيًا
عقد الـ API يساعد فقط إذا عكس ما تعتمد عليه فعلاً عملاء الويب والموبايل. مواصفة جميلة لا يستخدمها أحد لن تكتشف التغيير الذي يكسر الإنتاج.
ابدأ بالاستخدام الفعلي، لا بالتخمين. خذ أكثر استدعاءات العميل شيوعاً (من كود التطبيق، سجلات بوابة الـ API، أو قائمة قصيرة من الفرق) وحولها إلى حالات عقد: المسار الدقيق، الأسلوب، الرؤوس، معلمات الاستعلام، وشكل جسم الطلب النموذجي. هذا يجعل العقد صغيراً، ذا صلة، وصعب الجدل عليه.
شمل استجابات النجاح والفشل معاً. كثير من الفرق تختبر عقدياً مسار السعادة وتنسى أن العملاء يعتمدون على الأخطاء أيضاً: رمز الحالة، شكل جسم الخطأ، وحتى رموز/رسائل الأخطاء الثابتة. إذا عرض تطبيق الموبايل رسالة محددة "البريد الإلكتروني مستخدم بالفعل"، يجب على العقد تثبيت شكل استجابة 409 حتى لا يصبح فجأة 400 بجسم مختلف.
أعطِ اهتماماً خاصاً للمناطق التي تكسر كثيراً:
- الحقول الاختيارية مقابل المطلوبة: إزالة حقل عادةً أكثر أماناً من جعله مطلوباً.
- القيم null: بعض العملاء يتعاملون مع
nullبشكل مختلف عن "مفقود". قرر ما تسمح به وابقَ ثابتاً. - القوائم المحصورة (enums): إضافة قيمة جديدة يمكن أن تكسر العملاء الأقدم الذين يفترضون قائمة مغلقة.
- الترقيم (pagination): اتفق على المعاملات وحقول الاستجابة (مثل
cursorأوnextPageToken) وابقَ ثابتاً. - صيغ التواريخ والأرقام: وضحها صراحة (سلاسل ISO، سنتات كأعداد صحيحة، إلخ).
كيف تمثل العقد
اختر صيغة يمكن للفرق قراءتها وللأدوات التحقق منها. الخيارات الشائعة JSON Schema، عقود مستندة إلى أمثلة، أو نماذج مكتوبة تُولَّد من مواصفة OpenAPI. عملياً، تعمل الأمثلة إلى جانب فحص المخططات بشكل جيد: الأمثلة تُظهر أحمال حقيقية، بينما قواعد المخطط تكتشف أخطاء مثل "إعادة تسمية حقل" أو "تغيير نوع".
قاعدة بسيطة: إذا كان التغيير سيجبر على تحديث العميل، يجب أن يفشل اختبار العقد. هذه العقلية تبقي العقود مركزة على الكسور الحقيقية، لا على الكمال النظري.
خطوة بخطوة: أضف اختبارات العقود إلى خط CI
هدف اختبار العقود بسيط: عندما يغير أحدهم الـ API، يجب أن يخبرك CI ما إذا كان أي عميل ويب أو موبايل سيتعرض للكسر قبل أن يُنشر التغيير.
1) ابدأ بالتقاط ما يعتمد عليه العملاء فعلاً
اختر نقطة نهائية واحدة واكتب التوقعات المهمة في الاستخدام الحقيقي: الحقول المطلوبة، أنواع الحقول، القيم المسموح بها، رموز الحالة، واستجابات الأخطاء الشائعة. لا تحاول وصف الـ API كله دفعة واحدة. بالنسبة لتطبيقات الموبايل، شمل توقعات "نسخة التطبيق الأقدم" أيضاً، لأن المستخدمين لا يحدثون فوراً.
طريقة عملية: خذ بعض الطلبات الحقيقية التي يصنعها عملاؤك اليوم (من السجلات أو تجهيزات الاختبار) وحولها إلى أمثلة قابلة للتكرار.
2) ضع العقود حيث ستحافظ عليها الفرق
تفشل العقود عندما تعيش في مجلد منسي. ابقها قريبة من الكود الذي يتغير:
- إذا كان فريق واحد يملك الجانبين، خزّن العقود مع مستودع الـ API.
- إذا كانت فرق مختلفة تملك الويب والموبايل والـ API، استخدم مستودعاً مشتركاً تملكه الفرق، ليس شخصاً واحداً.
- عامل تحديث العقود ككود: يُراجع، يُنسّخ، ويُناقَش.
3) أضف فحوصاً على الجانبين في CI
تريد إشارتين:
- تحقق المزود على كل بناء API: "هل يظل الـ API يلبّي كل العقود المعروفة؟"
- فحوص المستهلك على كل بناء عميل: "هل لا يزال هذا العميل متوافقاً مع العقد المنشور الأحدث؟"
هذا يلتقط المشاكل من كلا الاتجاهين. إذا غيّر الـ API حقل استجابة، يفشل خط مزود الـ CI. إذا بدأ العميل يتوقع حقلًا جديدًا، يفشل خط عميل CI حتى يدعمّه الـ API.
4) قرر قاعدة الفشل وطبقها
كن صريحاً بشأن ما يمنع الدمج أو الإصدار. قاعدة شائعة: أي تغيير يكسر العقد يفشل CI ويمنع الدمج إلى الفرع الرئيسي. إذا احتجت استثناءات، اجعلها قراراً مكتوباً (مثلاً، تاريخ إصدار منسق).
مثال ملموس: يعيد الخادم totalPrice باسم total_amount. تفشل عملية التحقق من المزود فوراً، فيضيف فريق الخادم الحقل الجديد مع الإبقاء على القديم لفترة انتقالية، ويستمر كل من الويب والموبايل في النشر بأمان.
الإصدار والتوافق الرجعي بدون إبطاء الفرق
الفرق السريعة تكسر الـ APIs غالباً بتغيير ما تعتمد عليه العملاء الحاليون. "التغيير المسبب للكسر" هو أي شيء يجعل طلباً كان يعمل سابقاً يفشل، أو يجعل الاستجابة مختلفة بشكل يجعل العميل غير قادر على التعامل.
فيما يلي تغييرات شائعة تسبب كسرًا (حتى لو بقيت النقطة النهائية موجودة):
- إزالة حقل استجابة يقرأه العملاء
- تغيير نوع حقل (مثل
"total": "12"إلى"total": 12) - جعل حقل اختياري مطلوباً (أو إضافة حقل طلب جديد مطلوب)
- تغيير قواعد المصادقة (نقطة نهاية عامة أصبحت تحتاج توكن)
- تغيير رموز الحالة أو شكل الأخطاء التي يحللها العملاء (200 إلى 204، أو نموذج خطأ جديد)
معظم الفرق يمكنها تجنب رفع نسخة جديدة عن طريق بدائل أكثر أماناً. إذا احتجت بيانات جديدة، أضف حقلًا جديداً بدلاً من إعادة تسمية واحد. إذا احتجت نقطة نهاية أفضل، أضف مساراً جديداً وابقَ على القديم. إذا أردت تشديد التحقق، تقبل الصيغ القديمة والجديدة لفترة، ثم طبق القواعد تدريجياً. تساعد اختبارات العقود هنا لأنها تجبرك على إثبات أن المستهلكين الحاليين ما زالوا يحصلون على ما يتوقعونه.
التقادم (deprecation) هو الجزء الذي يحافظ على السرعة دون إيذاء المستخدمين. عملاء الويب قد يتحدثون يومياً، لكن تطبيقات الموبايل قد تتأخر لأسابيع بسبب قوائم المراجعة وقواعد النشر. خطط للتقادم بناءً على سلوك العملاء الفعلي، لا على الأمل.
سياسة تقادم عملية تبدو هكذا:
- أعلن التغيير مبكراً (ملاحظات إصدار، قناة داخلية، تذكرة)
- احتفظ بالسلوك القديم حتى ينخفض الاستخدام تحت عتبة متفق عليها
- أعد تحذيرات في الرؤوس/السجلات عند استخدام المسار المهمل
- حدد تاريخ إزالة فقط بعد التأكد من أن معظم العملاء قد حدثوا
- احذف السلوك القديم فقط بعد أن تظهر اختبارات العقد أنه لا يوجد مستهلك نشط يحتاجه
استخدم الترقيم الصريح فقط عندما لا يمكنك جعل التغيير متوافقاً رجعياً (مثلاً، تغيير جوهري في شكل المورد أو نموذج الأمان). الترقيم يضيف تكلفة طويلة الأمد: الآن عليك صيانة سلوكين، مجموعتي وثائق، والمزيد من حالات الحافة. اجعل الإصدارات نادرة ومتعمدة، واستخدم العقود للتأكد من أن كلتا النسختين صادقتان حتى يصبح القديم آمناً للحذف.
أخطاء شائعة في اختبار العقود (وكيف تتجنبها)
اختبار العقود يعمل أفضل عندما يراجع توقعات حقيقية، لا نسخة لعبة من نظامك. معظم الإخفاقات تنبع من أنماط متوقعة تجعل الفرق تشعر بالأمان بينما ما زالت الأخطاء تتسرّب إلى الإنتاج.
الخطأ 1: التعامل مع العقود كـ "محاكيات فاخرة"
الإفراط في المحاكاة هو الفخ الكلاسيكي: ينجح اختبار العقد لأن سلوك المزود تم محاكاته ليتطابق مع العقد، وليس لأن الخدمة الحقيقية قادرة عليه. عند النشر، يفشل أول استدعاء حقيقي.
قاعدة أكثر أماناً بسيطة: يجب التحقق من العقود ضد مزود قيد التشغيل (أو بناء قابل للتشغيل يتصرف بالمثل)، مع تسلسل حقيقي، تحقق حقيقي، وقواعد مصادقة حقيقية.
الأخطاء التي تظهر غالباً والحل الذي يثبت فعاليته:
- الإفراط في محاكاة سلوك المزود: تحقّق من العقود ضد بناء مزود حقيقي، لا خدمة وهمية.
- جعل العقود صارمة جداً: استخدم تطابقاً مرناً للأشياء مثل المعرفات، الطوابع الزمنية، والمصفوفات؛ تجنب التأكيد على كل حقل إذا كان العملاء لا يعتمدون عليها.
- تجاهل استجابات الأخطاء: اختبر على الأقل حالات الأخطاء الأعلى (401، 403، 404، 409، 422، 500) وشكل جسد الخطأ الذي يحلله العميل.
- لا مالك واضح: عين من يحدث العقد عند تغيير المتطلبات؛ اجعله جزءاً من "تعريف جاهزية" لتغييرات الـ API.
- نسيان واقعيات الموبايل: اختبر مع شبكات أبطأ ونُسخ تطبيق أقدم في الاعتبار، لا فقط أحدث بناء على Wi‑Fi سريع.
الخطأ 2: عقود هشة تمنع تغييرات غير ضارة
إذا فشل العقد عند إضافة حقل اختياري جديد أو إعادة ترتيب مفاتيح JSON، سيتعلم المطورون تجاهل البِناء الأحمر. هذا يُفقد الغرض.
اسعَ إلى "صرامة حيث يهم". كن صارماً بشأن الحقول المطلوبة، الأنواع، قيم enum والقيود. كن مرناً بشأن الحقول الإضافية، الترتيب، والقيم التي تتغير طبيعياً.
مثال صغير: يغيّر الخادم status من "active" | "paused" إلى "active" | "paused" | "trial". إذا كان تطبيق الموبايل يتعامل مع القيم المجهولة كخطأ يتسبب في انهيار، فهذا تغيير كاسر. يجب أن يلتقط العقد ذلك بفحص كيفية تعامل العميل مع قيم enum غير المعروفة، أو يتطلب من المزود الإبقاء على القيم المعروفة حتى تتعامل كل العملاء مع القيمة الجديدة.
تستحق تطبيقات الموبايل عناية إضافية لأنها تبقى أطول في التداول. قبل إعلان تغيير API "آمن":
- هل يمكن لنسخ التطبيق الأقدم أن تحلل الاستجابة؟
- ماذا يحدث إذا أعيد طلب الطلب بعد مهلة؟
- هل ستتعارض البيانات المخبأة مع الصيغة الجديدة؟
- هل لدينا نسخة احتياطية عندما يغيب حقل ما؟
إذا كانت واجهات الـ API تُولد أو تُحدّث بسرعة (بما في ذلك منصات مثل AppMaster)، فالعقود تُعد حاجز حماية عملي: تتيح لك التحرك بسرعة بينما تثبت أن الويب والموبايل سيستمران في العمل بعد كل تغيير.
قائمة تحقق سريعة قبل الشحن لتغييرات الـ API
استخدم هذه القائمة مباشرة قبل الدمج أو الإصدار. مصممة لالتقاط التعديلات الصغيرة التي تسبب أكبر الحرائق عندما يسلم الويب والموبايل بسرعة. إذا كنت تستخدم اختبارات العقود بالفعل، تساعدك هذه القائمة على التركيز على الكسور التي يجب أن تمنعها العقود.
الأسئلة الخمسة التي يجب طرحها في كل مرة
- هل أضفنا، أزلنا، أو أعدنا تسمية أي حقول استجابة يقرأها العملاء (بما في ذلك الحقول المتداخلة)؟
- هل تغيرت رموز الحالة (200 مقابل 201، 400 مقابل 422، 404 مقابل 410)، أو هل تغير شكل جسم الخطأ؟
- هل تقلبت أي حقول بين المطلوبة والاختيارية (بما في ذلك "يمكن أن تكون null" مقابل "يجب أن تكون موجودة")؟
- هل تغير الترتيب أو الترقيم أو الفلاتر الافتراضية (حجم الصفحة، الترتيب، رموز المؤشر)؟
- هل اختبارات العقد نفذت للمزود وكل المستهلكين النشطين (ويب، iOS، Android، وأي أدوات داخلية)؟
مثال بسيط: كان الـ API يعيد totalCount، ويستخدمه عميل لعرض "24 نتيجة". تزيله لأن "القائمة تحتوي أصلاً على عناصر". لا ينهار الخادم، لكن واجهة المستخدم تبدأ في إظهار فراغ أو "0 نتائج" لبعض المستخدمين. هذا كسر حقيقي، حتى لو بقيت نقطة النهاية تُعيد 200.
إذا أجبت "نعم" على أي بند
قم بهذه المتابعات السريعة قبل الشحن:
- أكد ما إذا كانت العملاء القديمة ستظل تعمل بدون تحديث. إذا لا، أضف مساراً متوافقاً رجعياً (احتفظ بالحقل القديم، أو دعم كلا الصيغتين لفترة).
- تحقق من معالجة الأخطاء في العملاء. كثير من التطبيقات تعامل أشكال الأخطاء المجهولة كـ "حدث خطأ ما" وتخفي رسائل مفيدة.
- شغّل اختبارات عقود المستهلك لكل نسخة عميل مدعومة، ليس الفرع الأحدث فقط.
إذا كنت تبني أدوات داخلية بسرعة (مثال: لوحة إدارة أو لوحة دعم)، تأكد من تضمين تلك المستهلكات أيضاً. في AppMaster، غالباً ما يولّد الفرق تطبيقات ويب وموبايل من نفس نماذج الخلفية، مما يجعل من السهل نسيان أن تعديل مخطط صغير قد يكسر عميلاً منشوراً إذا لم يتحقق العقد في CI.
مثال: اكتشاف كسر قبل نشرة الويب والموبايل
تخيل إعداداً شائعاً: فريق الـ API ينشر عدة مرات يومياً، تطبيق الويب يسلم يومياً، وتطبيقات الموبايل تُنشر أسبوعياً (بسبب مراجعات المتاجر والنشرات التدريجية). الجميع يتحرك بسرعة، لذا الخطر الحقيقي ليس سوء النية، بل التعديلات الصغيرة التي تبدو غير ضارة.
تأتي تذكرة دعم تطلب تسمية أوضح في استجابة ملف المستخدم. يعيد فريق الـ API تسمية حقل في GET /users/{id} من phone إلى mobileNumber.
تبدو تلك التسمية أنيقة، لكنها تغيير كاسر. قد يعرض تطبيق الويب رقم هاتفاً فارغاً في صفحة الملف. والأسوأ، قد ينهار تطبيق الموبايل إذا اعتبر phone حقلًا مطلوبًا، أو يفشل التحقق عند حفظ الملف.
مع اختبار العقود، يتم اكتشاف هذا قبل وصوله للمستخدمين. هكذا يفشل عادةً، بحسب كيفية تشغيل الفحوص:
- يفشل بناء المزود (جانب الـ API): وظيفة CI للـ API تتحقق من المزود مقابل عقود المستهلكين المحفوظة للويب والموبايل. ترى أن المستهلكين ما زالوا يتوقعون
phone، لكن المزود الآن يعيدmobileNumber، فتفشل عملية التحقق ويُمنع النشر. - يفشل بناء المستهلك (جانب العميل): فريق الويب يحدث عقده ليطلب
mobileNumberقبل أن يقدمه الـ API. يفشل اختبار العقد لأن المزود لا يزال لا يوفر ذلك الحقل.
في أيٍ من الحالتين، الفشل مبكر وواضح ومحدد: يشير إلى النقطة النهائية والاختلاف في الحقل بدلاً من الظهور لاحقاً كـ "صفحة الملف مكسورة" بعد الإصدار.
الحل عادة بسيط: اجعل التغيير إضافياً، لا مدمرًا. يعيد الـ API كلا الحقلين لفترة:
- أضف
mobileNumber. - احتفظ بـ
phoneكاسم مُرادف (نفس القيمة). - علّن
phoneكمهمل في ملاحظات العقد. - حدّث الويب والموبايل لقراءة
mobileNumber. - احذف
phoneفقط بعد رؤية أن جميع نسخ العملاء المدعومة تحولت.
جدول زمني واقعي تحت ضغط الإصدار قد يبدو هكذا:
- الاثنين 10:00: يضيف فريق الـ API
mobileNumberويحتفظ بـphone. تجتاز اختبارات العقد للمزود. - الاثنين 16:00: يبدّل الويب إلى
mobileNumberوينشر. - الخميس: يبدّل الموبايل إلى
mobileNumberويقدّم إصداراً. - الثلاثاء التالي: يصل إصدار الموبايل لمعظم المستخدمين.
- Sprint التالي: يزيل الـ API
phone، وتؤكد اختبارات العقد أن لا مستهلك مدعوم ما زال يحتاجه.
هذه هي القيمة الأساسية: تحوّل اختبارات العقود لعبة "اليانصيب التغييري" إلى انتقال مُتحكَّم ومؤقت.
خطوات قادمة للفرق السريعة (بما في ذلك خيار بدون كود)
إذا أردت لاختبارات العقود أن تمنع الكسور فعلاً (وليس مجرد إضافة فحوص إضافية)، فابعِد النشر ووضّح الملكية. الهدف بسيط: التقاط التغييرات المسببة للكسر قبل أن تضرب إصدارات الويب والموبايل.
ابدأ بخطة طرح خفيفة. اختر أهم 3 نقاط نهاية تسبب أكبر ألم عند تغييرها، عادة المصادقة، ملف المستخدم، ونقطة "قائمة أو بحث" أساسية. عقد عليها أولاً، ثم وسّع عندما يثق الفريق في سير العمل.
طرح عملي يبقى قابلاً للإدارة:
- الأسبوع 1: اختبارات العقود لأفضل 3 نقاط نهاية، تعمل على كل طلب سحب
- الأسبوع 2: أضف الخمسة نقاط التالية ذات أعلى استخدام موبايل
- الأسبوع 3: غطِ استجابات الأخطاء وحالات الحافة (الحالات الفارغة، أخطاء التحقق)
- الأسبوع 4: اجعل "نجاح العقد" بوابة لإصدار تغييرات الخادم
بعد ذلك، قرر من يفعل ماذا. الفرق تتحرك أسرع عندما يكون واضحاً من يملك الفشل ومن يوافق على التغيير.
اجعل الأدوار بسيطة:
- مالك العقد: عادة فريق الخادم، مسؤول عن تحديث العقود عند تغير السلوك
- مراجعي المستهلك: قادة الويب والموبايل الذين يؤكدون أمان التغييرات لعملائهم
- شرطي البنية: يتناوب يومياً أو أسبوعياً، يصنّف إخفاقات اختبارات العقد في CI
- مالك الإصدار: يتخذ قرار منع الإصدار إذا انكسر العقد
تتبع مقياس نجاح واحد يهتم به الجميع. للعديد من الفرق، أفضل إشارة هي انخفاض التصحيحات العاجلة بعد الإصدارات وانخفاض "تراجعات العملاء" مثل انهيارات التطبيقات، الشاشات الفارغة، أو خلل الدفع المرتبط بتغييرات الـ API.
إذا كنت تريد دورة رد فعل أسرع، المنصات بدون كود يمكن أن تقلل الانحراف عن طريق إعادة توليد كود نظيف بعد التغييرات. عند تحول المنطق أو نماذج البيانات، تساعد عملية التجدد على تجنُّب تراكم التعديلات التي تغير السلوك عن غير قصد.
إذا كنت تبني APIs والعملاء باستخدام AppMaster، خطوة عملية التالية هي التجربة الآن بإنشاء تطبيق، نمذجة بياناتك في Data Designer (PostgreSQL)، تحديث سير العمل في Business Process Editor، ثم إعادة التوليد والنشر إلى السحابة (أو تصدير الشيفرة المصدرية). أقرن ذلك بفحوص العقود في CI حتى يثبت كل بناء مُعاد توليده أنه لا يزال يطابق ما تتوقعه الويب والموبايل.


