اختبار التكامل

اختبار التكامل (Integration Testing) مستوى اختبار يركّز على التفاعلات بين المكونات أو بين الأنظمة. فقد ينجح كل جزء في اختباراته الخاصة، لكن اختبار التكامل يسأل: هل تعمل الأجزاء معاً؟ وهل البيانات التي يرسلها جزء هي ما يتوقعه الجزء الآخر، بالصيغة والوحدات والترتيب والتوقيت التي يتوقعها؟ مثال: يرسل مكوّن إتمام الطلب (Checkout) القيمة "amount": 150.00 قاصداً ⁦150⁩ ريالاً إلى بوابة دفع تقرأ المبالغ بالهللات، فيُخصم من العميل ⁦1.50⁩ ريال. فالعيب ليس في أيٍّ من المكونين، بل في الواجهة بينهما.

ويميّز منهج ISTQB للمستوى التأسيسي (الإصدار ⁦4.0⁩) بين مستويين للتكامل: تكامل المكونات وتكامل الأنظمة، وهما موضّحان أدناه. وكلاهما يُبنى على اختبار المكونات: فالأجزاء التي ثبتت صحتها منفردةً تُجمع الآن معاً.

لماذا يهم

الواجهة (Interface) هي المكان الذي تلتقي فيه افتراضات شخصين. وحين يختلف فهمهما للاتفاق بين الطرفين (ريالات أم هللات، توقيت محلي أم UTC، حقل غائب أم قيمة null)، تنجح كل اختبارات المكونات ولا يظهر العيب إلا عند تشغيل الأجزاء معاً. ونادراً ما يكشفه بديل Stub، لأنه يُكتب عادةً بالافتراض نفسه الذي كُتبت به الشيفرة التي تستدعيه.

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

تكامل المكونات وتكامل الأنظمة

تركّز اختبارات التكامل على الواجهة: الاستدعاءات والرسائل والبيانات المتبادلة بين الأجزاء، وما يحدث حين يتعطل الطرف الآخر، لا على المنطق داخل كل مكوّن. وأساس الاختبار هو كل ما يصف الواجهة: مواصفة الواجهة البرمجية مثل مستند OpenAPI، وصيغ الرسائل، ومخططات التسلسل.

  • اختبار تكامل المكونات (Component Integration Testing): الواجهات بين مكونات النظام الواحد، مثل خدمة الطلبات حين تستدعي مكوّن المخزون. يؤتمته المطورون عادةً في مسار التكامل المستمر (CI).
  • اختبار تكامل الأنظمة (System Integration Testing): الواجهات مع أنظمة أخرى وخدمات خارجية، مثل بوابة دفع أو مزوّد رسائل نصية. يقوده المختبِرون عادةً، ويحتاج إلى بيئة قريبة من الإنتاج، وبيئة تجريبية (Sandbox) من الطرف الآخر، وتنسيق مع فريق لا تتحكم فيه.

دفعةً واحدة أم تدريجياً: من الأعلى أو من الأسفل، مع Stubs وDrivers

في التكامل دفعةً واحدة (Big-bang) تُجمع المكونات كلها مرة واحدة وتُختبر معاً. لا حاجة هنا إلى بدائل، لكن الاختبار لا يبدأ إلا حين يجهز كل جزء، وإذا فشل اختبار فقد يكون السبب في أي واجهة. وهذا مقبول في نظام صغير جداً؛ أما في نظام أكبر فقد يستغرق تحديد الواجهة المعطوبة وقتاً أطول من الاختبار نفسه.

أما التكامل التدريجي (Incremental) فيضيف مكوّناً واحداً أو بضعة مكونات في كل مرة، ويختبر كل واجهة جديدة قبل التالية، فيكون أول مشتبه به عند الفشل هو الواجهة المضافة للتو. وتحلّ محل الأجزاء الناقصة بدائلُ تعرّفت إليها في اختبار المكونات. فالبديل (Stub) يحلّ محل مكوّن مُستدعى ويعيد إجابات مُعدّة مسبقاً. والمشغّل (Driver) يحلّ محل المكوّن المُستدعي: سكربت اختبار أو عميل API يستدعي المكوّن قيد الاختبار كما كان سيفعل المستدعي الغائب.

  • من الأعلى إلى الأسفل (Top-down): ابدأ من القمة (نقطة نهاية API أو واجهة المستخدم) مع بدائل Stub للمكونات التي تحتها، ثم استبدلها واحداً تلو الآخر. يظهر المسار الرئيسي مبكراً، وتُختبر الحسابات والوصول إلى البيانات أخيراً، وقد تتعقّد البدائل التي يجب أن تعيد بيانات واقعية.
  • من الأسفل إلى الأعلى (Bottom-up): ابدأ بأدنى المكونات (الحسابات، والوصول إلى البيانات، وعملاء الخدمات الخارجية) تستدعيها مشغّلات، ثم اصعد. تُختبر الأسس مبكراً ويسهل تحديد موضع الإخفاق، لكن المسار الكامل لا يظهر إلا في النهاية.
  • وتجمع فرق كثيرة بين الأسلوبين فتلتقي في المنتصف، ويُسمّى ذلك التكامل الشطيري (Sandwich) أو الهجين (Hybrid).
يجمع التكامل دفعةً واحدة مكونات إتمام الطلب كلها في خطوة واحدة، فقد يشير الاختبار الفاشل إلى أي واجهة؛ أما من الأعلى فتحلّ المكونات الحقيقية محل بدائل Stub نزولاً، ومن الأسفل محل المشغّلات صعوداً، واجهةً بعد واجهة. نموذج مفاهيمي

دفعةً واحدة (Big-bang)

  1. 1بناء كل المكونات واختبار كل منها منفرداً
  2. 2جمعها كلها في خطوة واحدةمن checkout-api حتى payment-client
  3. 3يفشل اختبارقد يكون السبب في أي واجهةفشل
البدائل اللازمة:
لا شيء
متى يبدأ الاختبار:
حين يجهز كل جزء
يشير الإخفاق إلى:
أي واجهة من الواجهات
يظهر مبكراً · يُختبر أخيراً:
لا شيء مبكراً؛ كل شيء في النهاية

من الأعلى إلى الأسفل (Top-down)تدريجي

  1. 1البدء بـcheckout-apiبديل Stub مكان order-service
  2. 2order-service الحقيقي يحلّ محل بديلهبدائل Stub للمكونات التي تحته
  3. 3المكونات الدنيا الحقيقية تحلّ محل آخر البدائل
البدائل اللازمة:
بدائل Stub مكان المكونات المُستدعاة
متى يبدأ الاختبار:
بمجرد وجود الطبقة العليا
يشير الإخفاق إلى:
أولاً إلى الواجهة المضافة للتو
يظهر مبكراً · يُختبر أخيراً:
مبكراً: المسار الرئيسي · أخيراً: الحسابات والوصول إلى البيانات

من الأسفل إلى الأعلى (Bottom-up)تدريجي

  1. 1مشغّلات تستدعي أدنى المكوناتprice-calculator وinventory وpayment-client
  2. 2مشغّل يستدعي order-serviceمع المكونات الدنيا الحقيقية الآن
  3. 3checkout-api يحلّ محل المشغّل
البدائل اللازمة:
مشغّلات (Drivers) مكان المكونات المُستدعية
متى يبدأ الاختبار:
بمجرد وجود أدنى المكونات
يشير الإخفاق إلى:
أولاً إلى الواجهة المضافة للتو
يظهر مبكراً · يُختبر أخيراً:
مبكراً: الأسس · أخيراً: المسار الكامل

جرّبها: مولّد استجابات API وهمية جرّبها: منشئ طلبات API

عيوب الواجهات: ما الذي تبحث عنه

تنشأ عيوب الواجهات من طرفين لا يتفقان، أو من طرف لا يُحسن التصرف حين يتعطل الطرف الآخر. وأول فحص عملي هو مقارنة الطلبات والاستجابات الفعلية لكل طرف بالمواصفة المتفق عليها، مثل مستند OpenAPI: فأي اختلاف يبيّن الطرف الذي يخالف الاتفاق. ثم اطرح هذه الأسئلة على كل واجهة:

  • الصيغة والترميز: هل 01/02/2026 هو الأول من فبراير أم الثاني من يناير؟ وهل تصل الأسماء العربية سليمة؟
  • الوحدات والمعنى: ريالات أم هللات، ثوانٍ أم أجزاء من الألف من الثانية، توقيت محلي أم UTC، سعر شامل ضريبة القيمة المضافة أم غير شامل.
  • البنية: حقل غائب أو أُعيدت تسميته أو زائد؛ قيمة null مقابل حقل غير موجود؛ قيم تعداد مختلفة (CANCELLED وCANCELED)؛ حدود طول مختلفة لدى كل طرف.
  • الترتيب والتوقيت: استدعاءات بترتيب خاطئ، أو استدعاء راجع (Callback) يصل قبل حفظ سجله، أو مهلة انتظار أقصر من زمن الاستجابة المعتاد للطرف الآخر.
  • معالجة الأعطال: حين يكون الطرف الآخر متوقفاً أو بطيئاً، أو يعيد الرمز ⁦500⁩ أو جسم خطأ غير متوقع، أو يجيب مرتين، هل يعيد المستدعي المحاولة بأمان، ويتجنب الخصم مرتين، ويُبقي البيانات متسقة؟

جرّبها: مدقّق عقود API جرّبها: مقارنة عقود الاستجابات

مثال تطبيقي: تكامل عملية إتمام الطلب

لعملية إتمام الطلب في متجر إلكتروني خمسة مكونات، وهي تستدعي نظاماً خارجياً واحداً، كما في الخطة أدناه. يدمج الفريق المكونات من الأسفل إلى الأعلى: فواجهة checkout-api تُكتب أخيراً، وحساب البيئة التجريبية لبوابة الدفع ما زال قيد الترتيب، لذا يحلّ بديل Stub محل البوابة في الخطوات من ⁦1⁩ إلى ⁦3⁩.

كُتب هذا البديل انطلاقاً من شيفرة عميل الدفع نفسه، فكان يقبل أي مبلغ، ونجحت كل الاختبارات في الخطوات من ⁦1⁩ إلى ⁦3⁩. ثم تُشغّل الخطوة ⁦4⁩ الاختبارات نفسها على البيئة التجريبية الحقيقية:

  • طلب بقيمة ⁦150.00⁩ ريال ينتج خصماً بقيمة ⁦1.50⁩ ريال: فالبوابة تتوقع عدداً صحيحاً من الهللات، والقيمة 150.00 في JSON هي ببساطة الرقم ⁦150⁩. ويذكر تقرير العيب الواجهة (من payment-client إلى البوابة) والطلب والاستجابة.
  • وتغطي الخطوة ⁦4⁩ أيضاً ما لا يُظهره إلا النظام الحقيقي: رموز الرفض الفعلية، وسلوكه عند انتهاء المهلة وإعادة المحاولة (خصم واحد فقط)، وتوقيت وصول الاستدعاء الراجع منه.
checkout-api               POST /checkout                          (top)
└── order-service          placeOrder(cart)
    ├── price-calculator   total(cart): SAR, 2 decimals
    ├── inventory          reserve(sku, qty), release(sku, qty)
    └── payment-client     charge(amount, currency)
            └──► payment gateway                        (external system)

Integration order: bottom-up
  1  drivers → price-calculator, inventory, payment-client   gateway: stub
  2  driver → order-service + the components from step 1    gateway: stub
  3  checkout-api replaces the driver                       gateway: stub
  4  the same tests, against the gateway sandbox            system integration

جرّبها: محاكي رموز حالة API جرّبها: مولّد استجابات خطأ وهمية

أخطاء شائعة

  • إعادة اختبار قواعد العمل داخل كل مكوّن بدلاً من الواجهة: البيانات المتبادلة، وترتيب الاستدعاءات، ومعالجة الأعطال.
  • الثقة ببديل Stub بُني على افتراضات المستدعي نفسه بدلاً من المواصفة المتفق عليها، وعدم الاختبار أبداً على النظام الحقيقي.
  • تكامل نظام كبير دفعةً واحدة، ثم قضاء أيام في البحث عن الواجهة المعطوبة.
  • اختبار المسار السعيد فقط، دون انتهاء المهلة أو الطلب المرفوض أو جسم الخطأ أو الاستدعاء الراجع المكرر.
  • طلب الوصول إلى البيئة التجريبية الخارجية متأخراً، فيُحشر اختبار تكامل الأنظمة في الأيام الأخيرة قبل الإصدار.
  • افتراض أن «اختبار التكامل» يعني الشيء نفسه للجميع. اسأل: أي الأجزاء حقيقية وأيها مُستبدَلة؟

من منظور ضمان الجودة

يبدأ عمل المختبِر في التكامل حين تُصمَّم الواجهات. اقرأ مواصفة الواجهة البرمجية ومخططات التسلسل أثناء جلسات التنقيح (Refinement)، واطرح على الطرفين الأسئلة نفسها: الوحدات والصيغ، والحقول الإلزامية، ورموز الأخطاء، ومهلة الانتظار، وإعادة المحاولة. فالخلاف الذي يُحسم حينها لا يصبح عيباً أبداً.

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

تمرين عملي

خطّط لاختبار تكامل تذكير المواعيد

المطلوب

يرسل تطبيق عيادة رسالة نصية للتذكير قبل كل موعد بـ⁦24⁩ ساعة، وأجزاؤه موضّحة أدناه. ما زالت واجهة booking-api قيد الكتابة، والبيئة التجريبية لدى مزوّد الرسائل النصية ستجهز بعد أسبوعين. خطّط لاختبار التكامل.

المادة
booking-api                  POST /appointments                     (top)
└── appointment-service      book(patient, slot), cancel(id), sendDueReminders(now)
    ├── schedule-repository  save(appointment), findDue(now)
    └── sms-client           send(phone, text, sendAt)
            └──► SMS provider  POST /v1/messages           (external system)

Clinic data: phone numbers as typed by staff (e.g. 05XXXXXXXX),
             appointment times in Riyadh time (UTC+3)

send(phone, text, sendAt)
  phone    international format (E.164), e.g. +9665XXXXXXXX
  text     reminder text, Arabic or English
  sendAt   ISO 8601 date-time, UTC

SMS provider responses
  202 {"id": "msg-123", "status": "queued"}
  400 invalid number    429 too many requests    503 unavailable
الخطوات
  1. صنّف كل واجهة: تكامل مكونات أم تكامل أنظمة.
  2. اختر ترتيب التكامل، واذكر بدائل Stub والمشغّلات (Drivers) التي يحتاجها.
  3. اكتب خمسة شروط اختبار تكامل لمسار التذكير، يذكر كل منها عيب الواجهة الذي يستهدفه.
  4. اذكر ما يجب فحصه على المزوّد الحقيقي.
إظهار الإجابة النموذجية
الإجابة النموذجية

تكامل المكونات: الواجهة بين booking-api وappointment-service، وبين appointment-service وschedule-repository، وبين appointment-service وsms-client. وتكامل الأنظمة: الواجهة بين sms-client ومزوّد الرسائل النصية.

من الأسفل إلى الأعلى، لأن الطبقة العليا غير جاهزة: ادمج schedule-repository وsms-client، ثم appointment-service. ويستدعي مشغّلٌ (سكربت اختبار أو عميل API) الدالتين book وcancel إلى أن تحلّ booking-api محله، ويستدعي sendDueReminders بقيمة now يختارها، فتصبح شروط التوقيت قابلة للتكرار. ويؤدي بديل Stub دور مزوّد الرسائل فيعيد ⁦202⁩ و⁦400⁩ و⁦429⁩ و⁦503⁩ واستجابة بطيئة.

شروط الاختبار: (⁦1⁩) موعد في الساعة ⁦10:00⁩ بتوقيت الرياض يعطي sendAt في الساعة ⁦07:00⁩ UTC من اليوم السابق (المنطقة الزمنية)؛ (⁦2⁩) الرقم 05XXXXXXXX يُرسَل بالصيغة +9665XXXXXXXX دون تكرار البادئة أبداً (الصيغة)؛ (⁦3⁩) التذكير العربي يصل مقروءاً (الترميز)؛ (⁦4⁩) الرمز ⁦503⁩ أو انتهاء المهلة يُبقي الموعد ويعيد المحاولة لاحقاً مع إرسال رسالة واحدة فقط (معالجة الأعطال)؛ (⁦5⁩) الإلغاء قبل sendAt يعني عدم إرسال أي تذكير (الترتيب والتوقيت).

على المزوّد الحقيقي: أن استجاباته تطابق ما أعاده البديل (رموز الحالة وحقول جسم الاستجابة)، وأنه يقرأ sendAt بتوقيت UTC، واسم المرسل، وحدّ المعدّل (Rate limit) الفعلي، وطريقة احتساب طول الرسالة للنص العربي، وهل تعيد البيئة التجريبية الأخطاء كما يعيدها الإنتاج.

أسئلة شائعة

هل اختبار التكامل هو نفسه الاختبار من البداية إلى النهاية؟

لا. يستهدف اختبار التكامل واجهات محددة: مكوّنين، أو نظامك ونظاماً آخر. أما الاختبار من البداية إلى النهاية (End-to-End) فيتبع رحلة مستخدم كاملة عبر النظام كله، ويعبر واجهات كثيرة في آن واحد. وقد يكشف عيوب تكامل، لكنه أبطأ ويجعل تحديد الواجهة المعطوبة أصعب. ويأتي اختبار النظام والاختبار من البداية إلى النهاية في الدروس التالية.

من يُجري اختبار التكامل: المطورون أم المختبِرون؟

عادةً يؤتمت المطورون اختبارات تكامل المكونات، ويقود المختبِرون اختبار تكامل الأنظمة، وكثيراً ما يكون ذلك بالتعاون مع الطرف الخارجي. وتختلف الفرق في ذلك، فاتفقوا عليه صراحةً؛ وفي كل الأحوال يراجع المختبِر الواجهات المغطاة، وهل اختُبرت مسارات الخطأ.

يسمّي المطورون الاختبار الذي يستخدم قاعدة بيانات حقيقية اختبار تكامل. هل هذا صحيح؟

تستخدم فرق كثيرة المصطلح بهذا المعنى: أي اختبار مؤتمت يتجاوز وحدة واحدة، مثل خدمة مع قاعدة بياناتها الحقيقية أو استدعاء HTTP حقيقي. وهذا يتفق مع التعريف العام، أي التفاعل بين الأجزاء. وحين يقول أحدهم «اختبار تكامل»، اسأل أي الأجزاء حقيقية وأيها مُستبدَلة، فذلك يخبرك بما يستطيع الاختبار كشفه وما لا يستطيع.

ما علاقة التكامل المستمر باختبار التكامل؟

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

المراجع

  • ISTQB Certified Tester Foundation Level (CTFL) v4.0ISTQB · 2023المنهج التأسيسي لاختبار البرمجيات: مستويات الاختبار وأنواعه وتقنيات تصميم الاختبارات وإدارة الاختبار والأدوات.
  • ISTQB GlossaryISTQBالتعريفات القياسية لمصطلحات الاختبار — حالة الاختبار واختبار الانحدار والخطورة والأولوية وتحليل القيم الحدّية وغيرها.
  • The Practical Test Pyramid (Ham Vocke)martinfowler.com · 2018شرح واسع الاستشهاد لكيفية الموازنة بين اختبارات الوحدة والتكامل والعقود والواجهة في محفظة الاختبارات الآلية.
  • Continuous Integration (Martin Fowler)martinfowler.com · 2024الوصف الأكثر استشهاداً للتكامل المستمر: ادمج كثيراً، واجعل البناء يختبر نفسه وسريعاً، وأصلح البناء المكسور فوراً.

تدرّب بأدوات متقن

ولّد استجابات API وهمية كاملة (الحالة والترويسات وجسم JSON) لحالات النجاح والقوائم والتفاصيل والأخطاء والنتائج الفارغة.

المحاكاة

احصل على نقطة نهاية عامة تعيد أي رمز حالة HTTP، مع تأخير اختياري وجسم JSON مخصّص، لاختبار معالجة الأخطاء في العميل.

اختبار واجهات API

ولّد استجابات خطأ منظّمة (التحقق والمصادقة وعدم العثور وتحديد المعدّل وخطأ الخادم) بالصيغ الشائعة.

المحاكاة

التحقق من مطابقة زوج طلب/استجابة API لعقد OpenAPI الخاص به: المسار والطريقة والمعاملات والجسم ومخطط الاستجابة.

التحقق

مقارنة استجابة API فعلية بعقد متوقَّع (مثال أو مخطط) والإبلاغ عن الفروق الكاسرة وغير الكاسرة.

التحقق

أنشئ طلبات HTTP وأرسلها (الطريقة وعنوان URL والترويسات والمصادقة والجسم) وافحص الاستجابة — بديل خفيف لـ Postman داخل متصفحك.

اختبار واجهات API

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة