Introducción: ¿por qué Docker y Swift son la pareja ideal para las pruebas de integración?
\n\nEl desarrollo moderno para iOS y macOS requiere no solo pruebas unitarias, sino también pruebas de integración completas. Cuando su aplicación interactúa con una base de datos, API externas o el sistema de archivos, las pruebas aisladas de cada componente ya no son suficientes. Aquí es donde Docker viene al rescate.
\n\nDocker permite crear entornos idénticos para las pruebas, eliminando el problema de «en mi máquina funciona». Para los desarrolladores de Swift, esto es especialmente relevante: la contenerización permite probar aplicaciones Swift del lado del servidor (Vapor, Kitura), así como emular la infraestructura para aplicaciones iOS (bases de datos, cachés, colas de mensajes).
\n\nEn este artículo, analizaremos el ciclo completo de configuración de pruebas de integración de Swift con Docker: desde la creación del entorno de prueba hasta la ejecución en CI/CD.
\n\n1. Preparación del entorno: Docker y Swift
\n\n1.1. Instalación de Docker y Swift Toolchain
\n\nEn primer lugar, asegúrese de tener instalado:
\n- \n
- Docker Desktop (para macOS) o Docker Engine (para Linux) \n
- Swift Toolchain versión 5.7+ (se puede descargar desde swift.org) \n
- Xcode 14+ (si prueba componentes de iOS) \n
1.2. Creación del Dockerfile para Swift
\n\nEmpecemos creando una imagen Docker base para nuestra aplicación Swift. Cree un archivo Dockerfile en la raíz del proyecto:
# Dockerfile\nFROM swift:5.9-focal AS base\n\n# Establecemos el directorio de trabajo\nWORKDIR /app\n\n# Copiamos los archivos del manifiesto Package.swift\nCOPY Package.swift ./\nCOPY Sources/ ./Sources/\nCOPY Tests/ ./Tests/\n\n# Compilación del proyecto\nRUN swift build -c debug\n\n# Imagen final para pruebas\nFROM base AS test\nCMD ["swift", "test", "--parallel"]\n\n\nEsta imagen compila el proyecto y ejecuta las pruebas. Para las pruebas de integración, necesitaremos servicios adicionales.
\n\n2. Pruebas de integración con Docker Compose
\n\nDocker Compose permite ejecutar varios contenedores simultáneamente. Para un escenario típico, necesitaremos:
\n- \n
- Un contenedor con nuestra aplicación Swift \n
- Un contenedor con PostgreSQL (u otra base de datos) \n
- Un contenedor con Redis (para almacenamiento en caché) \n
2.1. Ejemplo de 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 especial para pruebas
\n\nCreemos un Dockerfile.test que espere a que las dependencias estén listas:
# Dockerfile.test\nFROM swift:5.9-focal\n\nWORKDIR /app\n\n# Instalamos netcat para verificar conexiones\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# Esperamos a PostgreSQL y 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\nScript wait-for-services.sh:
#!/bin/bash\n# wait-for-services.sh\n\necho "Esperando a PostgreSQL..."\nwhile ! nc -z postgres