اختبار التكامل C++ مع Docker: المستوى المتقدم
تطوير تطبيقات C++ الحديثة ينتقل بشكل متزايد إلى نموذج الخدمات المصغرة والحاويات. يصبح اختبار التكامل (Integration Testing) مرحلة حاسمة، تسمح بالتحقق من تفاعل مكونات النظام في ظروف أقرب ما تكون إلى ظروف الإنتاج. يوفر Docker بيئة مثالية للاختبار المعزول والقابل للتكرار. في هذه المقالة، سنستعرض تقنيات متقدمة لاختبار التكامل C++ باستخدام Docker، بما في ذلك إعداد الحاويات، كتابة الاختبارات باستخدام Google Test، والتكامل مع خطوط أنابيب CI/CD.
1. لماذا Docker هو الأداة المثالية لاختبار التكامل C++؟
اختبار الوحدات التقليدي يتحقق من الدوال أو الفئات الفردية، لكنه لا يضمن عمل النظام بأكمله بشكل صحيح. تتحقق اختبارات التكامل من الروابط: قواعد البيانات، بروتوكولات الشبكة، نظام الملفات، واجهات API الخارجية. هنا يصبح Docker لا غنى عنه:
- قابلية التكرار: تحتوي صورة Docker على نسخة طبق الأصل من البيئة (المترجم، المكتبات، متغيرات البيئة). الاختبار الذي ينجح محلياً سينجح على خادم CI وعند مطور آخر.
- العزل: يتم تشغيل كل اختبار في حاوية نظيفة. لا يوجد "تلوث" بإعدادات نظام التشغيل العامة أو بيانات متبقية من اختبارات سابقة.
- التوازي: يمكن تشغيل العديد من حاويات الاختبار في وقت واحد، مما يوفر الوقت في CI/CD.
- إدارة التبعيات: يسمح Docker Compose برفع بنية تحتية كاملة: PostgreSQL، Redis، Kafka — في غضون ثوانٍ.
2. إعداد بيئة الاختبار باستخدام Docker Compose
لننظر في سيناريو نموذجي: خدمة C++ تقرأ البيانات من PostgreSQL وترسلها إلى RabbitMQ. نحتاج لاختبار تكامل هذه المكونات الثلاثة.
سننشئ ملف docker-compose.test.yml:
version: '3.8'services: postgres_test: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"] interval: 5s timeout: 5s retries: 5
rabbitmq_test: image: rabbitmq:3-management-alpine environment: RABBITMQ_DEFAULT_USER: testuser RABBITMQ_DEFAULT_PASS: testpass ports: - "5672:5672" healthcheck: test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"] interval: 5s timeout: 5s retries: 5
test_runner: build: context: . dockerfile: Dockerfile.test depends_on: postgres_test: condition: service_healthy rabbitmq_test: condition: service_healthy environment: DB_HOST: postgres_test DB_PORT: 5432 DB_NAME: testdb DB_USER: testuser DB_PASS: testpass RMQ_HOST: rabbitmq_test RMQ_PORT: 5672النقطة الأساسية هي الفحص الصحي (healthcheck). نحن لا نبدأ الاختبارات حتى تصبح قاعدة البيانات ووسيط الرسائل جاهزين للعمل. هذا يمنع "حالة السباق" في الاختبارات.
3. كتابة اختبارات التكامل بلغة C++ باستخدام Google Test
للتظاهر، سنستخدم Google Test (gtest) — المعيار الفعلي لاختبار C++. سنكتب اختباراً يتحقق من إدراج البيانات في PostgreSQL وقراءتها عبر RabbitMQ.
أولاً، سننشئ غلافاً بسيطاً للعمل مع RabbitMQ (بشكل مبسط):
// rabbitmq_client.h#pragma once#include <string>#include <amqpcpp.h>
class RabbitMQClient {public: RabbitMQClient(const std::string& host, int port, const std::string& user, const std::string& pass); bool sendMessage(const std::string& queue, const