مقدمة: لماذا يعتبر Docker و Swift ثنائيًا مثاليًا لاختبار التكامل؟
\n\nالتطوير الحديث لنظامي iOS و macOS لا يتطلب اختبارات الوحدة فحسب، بل يتطلب أيضًا اختبار تكامل كامل. عندما يتفاعل تطبيقك مع قاعدة بيانات، أو واجهات برمجة تطبيقات خارجية، أو نظام الملفات، فإن الاختبار المعزول لكل مكون لم يعد كافيًا. هنا يأتي دور Docker.
\n\nيتيح Docker إنشاء بيئات متطابقة للاختبارات، مما يلغي مشكلة "يعمل على جهازي". بالنسبة لمطوري Swift، هذا مهم بشكل خاص: تتيح الحاويات اختبار تطبيقات Swift من جانب الخادم (Vapor, Kitura)، بالإضافة إلى محاكاة البنية التحتية لتطبيقات iOS (قواعد البيانات، التخزين المؤقت، قوائم انتظار الرسائل).
\n\nفي هذه المقالة، سنشرح الدورة الكاملة لإعداد اختبار التكامل لـ Swift مع Docker: من إنشاء بيئة الاختبار إلى التشغيل في CI/CD.
\n\n1. إعداد البيئة: Docker و Swift
\n\n1.1. تثبيت Docker و Swift Toolchain
\n\nأولاً، تأكد من تثبيت ما يلي:
\n- \n
- Docker Desktop (لنظام macOS) أو Docker Engine (لنظام Linux) \n
- Swift Toolchain الإصدار 5.7+ (يمكن تنزيله من swift.org) \n
- Xcode 14+ (إذا كنت تختبر مكونات iOS) \n
1.2. إنشاء Dockerfile لـ Swift
\n\nلنبدأ بإنشاء صورة Docker أساسية لتطبيق Swift الخاص بنا. قم بإنشاء ملف Dockerfile في جذر المشروع:
# Dockerfile\nFROM swift:5.9-focal AS base\n\n# تعيين دليل العمل\nWORKDIR /app\n\n# نسخ ملفات البيان Package.swift\nCOPY Package.swift ./\nCOPY Sources/ ./Sources/\nCOPY Tests/ ./Tests/\n\n# بناء المشروع\nRUN swift build -c debug\n\n# الصورة النهائية للاختبارات\nFROM base AS test\nCMD ["swift", "test", "--parallel"]\n\n\nتقوم هذه الصورة ببناء المشروع وتشغيل الاختبارات. بالنسبة لاختبارات التكامل، سنحتاج إلى خدمات إضافية.
\n\n2. اختبار التكامل باستخدام Docker Compose
\n\nيتيح Docker Compose تشغيل عدة حاويات في وقت واحد. بالنسبة لسيناريو نموذجي، سنحتاج إلى:
\n- \n
- حاوية تحتوي على تطبيق Swift الخاص بنا \n
- حاوية تحتوي على PostgreSQL (أو قاعدة بيانات أخرى) \n
- حاوية تحتوي على Redis (للتخزين المؤقت) \n
2.1. مثال على docker-compose.yml
\n\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n postgres:\n image: postgres:15\n environment:\n POSTGRES_USER: test_user\n POSTGRES_PASSWORD: test_pass\n POSTGRES_DB: test_db\n ports:\n - "5432:5432"\n healthcheck:\n test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n interval: 5s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n ports:\n - "6379:6379"\n\n swift-tests:\n build:\n context: .\n dockerfile: Dockerfile.test\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_started\n environment:\n DATABASE_URL: "postgres://test_user:test_pass@postgres:5432/test_db"\n REDIS_URL: "redis://redis:6379"\n volumes:\n - .:/app\n\n\n2.2. Dockerfile خاص للاختبارات
\n\nلنقم بإنشاء Dockerfile.test الذي سينتظر جاهزية التبعيات:
# Dockerfile.test\nFROM swift:5.9-focal\n\nWORKDIR /app\n\n# تثبيت netcat للتحقق من الاتصالات\nRUN apt-get update && apt-get install -y netcat-openbsd && rm -rf /var/lib/apt/lists/*\n\nCOPY Package.swift ./\nRUN swift package resolve\n\nCOPY . .\n\n# انتظار PostgreSQL و Redis\nCOPY wait-for-services.sh /usr/local/bin/\nRUN chmod +x /usr/local/bin/wait-for-services.sh\n\nCMD ["wait-for-services.sh"]\n\n\nالبرنامج النصي wait-for-services.sh:
#!/bin/bash\n# wait-for-services.sh\n\necho "Waiting for PostgreSQL..."\nwhile ! nc -z postgres