اختبار التكامل لجافا سكريبت مع Docker: المستوى المتقدم
اختبار التكامل هو مرحلة أساسية في تطوير تطبيقات الويب الحديثة. فهو يسمح بالتحقق من التفاعل بين المكونات المختلفة للنظام: قاعدة البيانات، ذاكرة التخزين المؤقت، واجهات API الخارجية والتطبيق نفسه. يجعل Docker هذه العملية قابلة للتنبؤ، معزولة وقابلة للتكرار. في هذه المقالة، سنستعرض تقنيات متقدمة لاختبار التكامل لجافا سكريبت (Node.js) باستخدام Docker.
لماذا Docker في اختبار التكامل؟
يواجه اختبار التكامل التقليدي مشاكل:
- الاختلافات في بيئات المطور، CI والإنتاج.
- تلوث البيانات في قواعد البيانات المشتركة.
- صعوبة تشغيل التبعيات (Redis, PostgreSQL, Kafka).
يحل Docker هذه المشاكل من خلال توفير حاويات خفيفة ومعزولة. يمكن لكل اختبار تشغيل بنيته التحتية الخاصة، وتدميرها بعد الانتهاء. وهذا يضمن نقاء النتائج وقابليتها للتكرار.
إعداد بيئة الاختبار مع Docker Compose
للاختبار المتقدم، سنستخدم docker-compose.yml الذي يصف جميع الخدمات اللازمة للاختبارات: التطبيق نفسه، قاعدة البيانات، ذاكرة التخزين المؤقت وخوادم المحاكاة.
مثال docker-compose.test.yml:
version: '3.8'services: app: build: . environment: - NODE_ENV=test - DB_HOST=postgres_test - REDIS_HOST=redis_test - MOCK_SERVER_URL=http://mock-server:8080 depends_on: - postgres_test - redis_test - mock-server command: ["npm", "run", "test:integration"]
postgres_test: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test tmpfs: /var/lib/postgresql/data
redis_test: image: redis:7-alpine tmpfs: /data
mock-server: image: mockserver/mockserver:latest environment: MOCKSERVER_LOG_LEVEL: ERRORالنقاط الرئيسية:
- tmpfs: يتم تخزين بيانات قاعدة البيانات وRedis في الذاكرة العشوائية، مما يسرع الاختبارات.
- mock-server: خدمة معزولة لمحاكاة واجهات API الخارجية.
- NODE_ENV=test: يحول التطبيق إلى تكوين الاختبار.
كتابة اختبارات التكامل مع Testcontainers
مكتبة testcontainers لـ Node.js تسمح بإدارة الحاويات برمجياً مباشرة من الاختبارات. وهذا يوفر مرونة: يمكنك تشغيل حاويات محددة لكل مجموعة اختبار.
التثبيت:
npm install --save-dev testcontainersمثال اختبار مع PostgreSQL:
const { GenericContainer } = require('testcontainers');const { Client } = require('pg');
describe('User Repository Integration Test', () => { let container; let client;
beforeAll(async () => { // تشغيل حاوية PostgreSQL container = await new GenericContainer('postgres:15-alpine') .withEnvironment({ POSTGRES_DB: 'testdb', POSTGRES_USER: 'test', POSTGRES_PASSWORD: 'test' }) .withExposedPorts(5432) .start();
// الاتصال بالحاوية client = new Client({ host: container.getHost(), port: container.getMappedPort(5432), database: 'testdb', user: 'test', password: 'test' }); await client.connect();
// إنشاء المخطط await client.query(` CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) UNIQUE ) `); });
afterAll(async () => { await client.end(); await container.stop(); });
test('should insert and retrieve user', async () => { await client.query(