اختبار التكامل لجافا سكريبت مع Docker: من النظرية إلى التطبيق المتقدم
\n\nاختبار التكامل هو مرحلة حاسمة في التطوير تتحقق من التفاعل بين الوحدات المختلفة والخدمات الخارجية. بالنسبة لتطبيقات جافا سكريبت على Node.js، يصبح Docker أداة لا غنى عنها، مما يسمح بإنشاء بيئات اختبار معزولة وقابلة للتكرار. في هذه المقالة، سنستعرض تقنيات متقدمة لإعداد اختبارات التكامل مع Docker، بما في ذلك العمل مع قواعد البيانات، قوائم الانتظار، وتحسين CI/CD.
\n\nلماذا Docker لاختبارات التكامل؟
\n\nالأساليب التقليدية لاختبار التكامل (mocks, stubs) لا تعكس دائمًا السلوك الحقيقي للنظام. يحل Docker هذه المشكلة من خلال توفير:
\n\n- \n
- العزل: يتم تشغيل كل اختبار في حاوية نظيفة دون التأثير على الاختبارات الأخرى أو البيئة المحلية. \n
- قابلية التكرار: نفس ظروف التشغيل على جهاز المطور وفي CI/CD. \n
- قابلية التوسع: إمكانية تشغيل الاختبارات بالتوازي مع إصدارات مختلفة من التبعيات (PostgreSQL, Redis, Elasticsearch). \n
- الاستعادة السريعة: إعادة إنشاء الحاويات يستغرق ثوانٍ، وليس ساعات من الإعداد. \n
إعداد بيئة اختبار متقدمة
\n\nلنفكر في تطبيق Node.js نموذجي يستخدم PostgreSQL و Redis. بدلاً من docker-compose.yml البسيط، سننشئ تكوينًا مرنًا يدعم الاختبارات المتوازية وفحوصات الصحة.
الخطوة 1: Docker Compose مع منافذ ديناميكية
\n\nلتجنب تعارض المنافذ عند التشغيل المتوازي، نستخدم التخصيص الديناميكي:
\n\n# docker-compose.test.yml\nversion: '3.8'\nservices:\n postgres_test:\n image: postgres:15-alpine\n environment:\n POSTGRES_DB: test_db\n POSTGRES_USER: test_user\n POSTGRES_PASSWORD: test_pass\n ports:\n - "0:5432" # منفذ ديناميكي\n healthcheck:\n test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n interval: 2s\n timeout: 5s\n retries: 10\n tmpfs: /var/lib/postgresql/data # البيانات في RAM للسرعة\n\n redis_test:\n image: redis:7-alpine\n ports:\n - "0:6379"\n healthcheck:\n test: ["CMD", "redis-cli", "ping"]\n interval: 2s\n timeout: 5s\n retries: 10\n\nالخطوة 2: أدوات مساعدة لتشغيل الاختبارات مع Docker
\n\nسننشئ فئة مساعدة تبحث تلقائيًا عن المنافذ الديناميكية وتنتظر جاهزية الخدمات:
\n\n// test/setup/docker-manager.js\nconst { DockerComposeEnvironment, Wait } = require('testcontainers');\nconst { Client } = require('pg');\nconst Redis = require('ioredis');\n\nclass DockerTestManager {\n constructor() {\n this.environment = null;\n this.config = {\n pgPort: null,\n redisPort: null\n };\n }\n\n async start() {\n this.environment = await new DockerComposeEnvironment(\n '.', \n 'docker-compose.test.yml'\n ).withWaitStrategy('postgres_test', Wait.forHealthCheck())\n .withWaitStrategy('redis_test', Wait.forHealthCheck())\n .up();\n\n // استخراج تعيين المنافذ\n const pgContainer = this.environment.getContainer('postgres_test');\n const redisContainer = this.environment.getContainer('redis_test');\n \n this.config.pgPort = pgContainer.getMappedPort(5432);\n this.config.redisPort = redisContainer.getMappedPort(6379);\n \n return this.config;\n }\n\n async stop() {\n if (this.environment) {\n await this.environment.down();\n }\n }\n}\n\nmodule.exports = DockerTestManager;\n\nسيناريوهات متقدمة لاختبار التكامل
\n\nالآن سننتقل إلى اختبارات محددة تتحقق من التفاعل الحقيقي للمكونات.
\n