اختبار التكامل لـ Swift مع Docker: المستوى المتقدم
اختبار التكامل هو مرحلة أساسية في تطوير تطبيقات Swift الموثوقة. على عكس اختبارات الوحدة، فهو يتحقق من التفاعل بين المكونات الحقيقية: قاعدة البيانات، الخدمات الشبكية، نظام الملفات. يتيح Docker عزل هذه التبعيات، مما يجعل الاختبارات قابلة للتكرار ومستقلة عن بيئة المطور. في هذه المقالة، سنستعرض التقنيات المتقدمة لاختبار التكامل لتطبيقات Swift (iOS والجانب الخادم) باستخدام Docker.
1. أساسيات حاويات Docker لاختبارات Swift
قبل التعمق في السيناريوهات المتقدمة، من المهم فهم البنية الأساسية. يتيح Docker تشغيل التبعيات (PostgreSQL، Redis، خوادم المحاكاة) في حاويات معزولة، يتم تشغيلها تلقائيًا قبل الاختبارات وتدميرها بعد ذلك.
بالنسبة لـ Swift من جانب الخادم (Vapor، Kitura)، نستخدم الصورة الرسمية لـ Swift. بالنسبة لتطبيقات iOS، لا يمكن لـ Docker تشغيل المحاكي، ولكنه مناسب تمامًا لاختبار الطبقة الشبكية والخلفية.
مثال على ملف Docker Compose أساسي لمشروع Vapor:
version: '3.8'services: app: image: swift:5.10-focal working_dir: /app volumes: - .:/app depends_on: - db - redis environment: - DATABASE_URL=postgres://user:pass@db:5432/testdb - REDIS_URL=redis://redis:6379
db: image: postgres:16-alpine environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: testdb ports: - "5432:5432"
redis: image: redis:7-alpine ports: - "6379:6379"يقوم هذا الملف بتشغيل ثلاث حاويات: خادم Swift نفسه، PostgreSQL، وRedis. الآن سنكتب اختبار تكامل يتحقق من حفظ مستخدم في قاعدة بيانات حقيقية.
2. كتابة اختبارات التكامل باستخدام XCTest وDocker
لاختبار التكامل لـ Swift من جانب الخادم، سنستخدم الإطار القياسي XCTest. النقطة الأساسية هي أن الاختبارات يجب أن تُشغل داخل الحاوية التي لديها وصول إلى الحاويات الأخرى.
مثال على اختبار لتطبيق Vapor:
import XCTest@testable import Appimport Vapor
final class UserIntegrationTests: XCTestCase {
var app: Application!
override func setUp() async throws { app = try await Application.make(.testing) try await configure(app)
// ترحيل قاعدة البيانات قبل كل اختبار try await app.autoMigrate() }
override func tearDown() async throws { try await app.autoRevert() try await app.asyncShutdown() }
func testCreateAndFetchUser() async throws { // إنشاء مستخدم عبر API let userDTO = UserDTO(name: "Alice", email: "alice@test.com") try await app.test(.POST, "/users", beforeRequest: { req in try req.content.encode(userDTO) }, afterResponse: { res in XCTAssertEqual(res.status, .created) let createdUser = try res.content.decode(User.self) XCTAssertEqual(createdUser.name, "Alice") })
// التحقق من حفظ المستخدم في قاعدة البيانات try await app.test(.GET, "/users/\\(aliceID)", afterResponse: { res in XCTAssertEqual(res.status, .ok) let fetchedUser = try res.content.decode(User.self) XCTAssertEqual(fetchedUser.email, "alice@test.com") }) }}يقوم هذا الاختبار بتشغيل التطبيق، وإجراء طلبات HTTP إلى الخادم الحقيقي داخل الحاوية، والتحقق من الردود. يضمن Docker أن قاعدة البيانات وRedis نظيفة لكل تشغيل.
3. خوادم المحاكاة (Mock) وعزل التبعيات الخارجية
على المستوى المتقدم، غالبًا ما يكون من الضروري اختبار التفاعل مع واجهات برمجة التطبيقات الخارجية (أنظمة الدفع، خدمات الطقس)