اختبار التكامل PHP مع Docker: المستوى المتقدم
اختبار التكامل هو مرحلة حاسمة في التطوير، خاصة لتطبيقات PHP المعقدة التي تتفاعل مع قواعد البيانات، قوائم الانتظار، واجهات API الخارجية والخدمات الأخرى. يتيح Docker إنشاء بيئة معزولة قريبة قدر الإمكان من بيئة الإنتاج، وتنفيذ الاختبارات في ظروف قابلة للتكرار. في هذه المقالة، سنستعرض التقنيات المتقدمة: تنظيم حاويات الاختبار، محاكاة التبعيات الخارجية، التشغيل المتوازي والتكامل مع CI/CD.
1. بنية بيئة الاختبار باستخدام docker-compose
لاختبارات التكامل، نستخدم ملف docker-compose.test.yml منفصل يقوم بتشغيل الخدمات الضرورية فقط: PHP-FPM مع كود الاختبار، قاعدة بيانات (مثل PostgreSQL)، Redis، واختيارياً خادم mock لواجهات API الخارجية.
version: '3.8'services: php-test: build: context: . dockerfile: Dockerfile.test volumes: - .:/var/www/html environment: DATABASE_URL: "pgsql://test:test@db-test:5432/testdb" REDIS_URL: "redis://redis-test:6379" EXTERNAL_API_URL: "http://mock-server:1080" depends_on: - db-test - redis-test - mock-server
db-test: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test ports: - "5433:5432" # تجنب التعارض مع قاعدة البيانات الرئيسية
redis-test: image: redis:7-alpine ports: - "6380:6379"
mock-server: image: mockserver/mockserver:latest environment: MOCKSERVER_PROPERTY_FILE: /config/mockserver.properties volumes: - ./tests/mockserver:/config ports: - "1080:1080"لاحظ أننا نستخدم منافذ منفصلة لخدمات الاختبار لتجنب التداخل مع التطوير المحلي.
2. إعداد PHPUnit وتهيئة قاعدة بيانات الاختبار
إعداد ملف phpunit.xml لاختبارات التكامل:
<phpunit bootstrap="tests/bootstrap.php"> <testsuites> <testsuite name="Integration"> <directory>tests/Integration</directory> </testsuite> </testsuites> <php> <env name="APP_ENV" value="test"/> <env name="KERNEL_CLASS" value="App\\Kernel"/> </php></phpunit>ملف tests/bootstrap.php مسؤول عن تهيئة هيكل قاعدة البيانات وتعبئتها ببيانات الاختبار:
require __DIR__ . '/../vendor/autoload.php';
// إنشاء هيكل قاعدة البيانات$pdo = new PDO('pgsql:host=db-test;port=5432;dbname=testdb', 'test', 'test');$pdo->exec(file_get_contents(__DIR__ . '/../migrations/schema.sql'));
// تحميل البيانات الثابتةrequire __DIR__ . '/Fixtures/LoadFixtures.php';يضمن هذا النهج أن كل تشغيل للاختبارات يبدأ من حالة نظيفة وقابلة للتنبؤ.
3. الاختبار مع واجهات API الخارجية: MockServer و WireMock
لمحاكاة خدمات HTTP الخارجية، نستخدم MockServer (أو WireMock). نقوم بإنشاء تكوين التوقعات في ملف JSON:
// tests/mockserver/expectations/payment.json{ "httpRequest": { "method": "POST", "path": "/api/v1/charge" }, "httpResponse": { "statusCode": 200, "body": "{\\"status\\": \\"success\\", \\"transaction_id\\": \\"txn_123\\"}", "headers": { "Content-Type": "application/json" } }}في كود PHP للاختبار، نرسل طلباً إلى URL حقيقي يشير عبر متغير البيئة إلى mock-server:
class PaymentIntegrationTest extends TestCase{ private PaymentService $paymentService;
protected function setUp(): void { $this->paymentService = new PaymentService( new HttpClient(['base_uri' => $_ENV['EXTERNAL_API_URL']])