testcontainers-go: Docker في اختبارات Go
في تطوير البرمجيات الحديثة، يُعد اختبار التكامل مع الخدمات الخارجية (قواعد البيانات، وسطاء الرسائل، أنظمة التخزين المؤقت) من أصعب المهام. الطرق التقليدية، مثل استخدام قواعد بيانات اختبار مشتركة أو كائنات وهمية (mocks)، غالباً ما تؤدي إلى مشاكل: تصبح الاختبارات هشة، وتعتمد على البيئة المحيطة، أو لا تعكس السلوك الحقيقي للنظام. تقدم مكتبة testcontainers-go حلاً أنيقاً: فهي تتيح تشغيل حاويات Docker معزولة مباشرة من كود الاختبار بلغة Go، مما يوفر بيئة نظيفة وقابلة للتكرار وقريبة من بيئة الإنتاج لكل تشغيل اختبار.
الفكرة الأساسية لـ testcontainers-go هي إدارة دورة حياة حاويات Docker برمجياً. تقوم بوصف الخدمة المطلوبة (مثل PostgreSQL، Redis، Kafka) في كود الاختبار، وتقوم المكتبة تلقائياً بتنزيل الصورة (إذا لم تكن موجودة)، وتشغيل الحاوية، وانتظار جاهزيتها، ثم تزويدك بمعلمات الاتصال (المضيف، المنفذ، بيانات الاعتماد). بعد انتهاء الاختبار، يتم إيقاف الحاوية وحذفها تلقائياً دون ترك أي بقايا في النظام. هذا يجعل الاختبارات مستقلة وسريعة وآمنة.
testcontainers-go هي تطبيق بلغة Go للمشروع الشهير Testcontainers، الذي ظهر في البداية بلغة Java ثم تم نقله إلى لغات أخرى. المكتبة مدعومة بنشاط من المجتمع وتوفر وحدات جاهزة لمعظم الخدمات الشائعة: PostgreSQL، MySQL، Redis، MongoDB، Kafka، RabbitMQ، Elasticsearch وغيرها الكثير. وهي مثالية لكتابة اختبارات التكامل، واختبارات النهاية إلى النهاية (end-to-end)، وحتى للتطوير المحلي عندما تحتاج إلى تشغيل بيئة بسرعة.
التثبيت
لتثبيت testcontainers-go، استخدم مدير الحزم القياسي للغة Go. تأكد من تثبيت Docker (أو Podman) وإصدار Go 1.19 أو أحدث.
go get github.com/testcontainers/testcontainers-go
للعمل مع خدمات محددة (مثل PostgreSQL)، ستحتاج إلى تثبيت الوحدة المقابلة:
go get github.com/testcontainers/testcontainers-go/modules/postgres
go get github.com/testcontainers/testcontainers-go/modules/redis
go get github.com/testcontainers/testcontainers-go/modules/mongodb
go get github.com/testcontainers/testcontainers-go/modules/kafka
# وهكذا
بعد التثبيت، قم باستيراد الحزم في ملف الاختبار الخاص بك:
import (
"context"
"testing"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
"github.com/testcontainers/testcontainers-go/modules/postgres"
)
بداية سريعة: مثال عملي بسيط
لنكتب اختباراً بسيطاً يقوم بتشغيل حاوية PostgreSQL، وإنشاء جدول، وإدراج بيانات، والتحقق منها. سيوضح لك هذا المبادئ الأساسية للعمل مع المكتبة.
package main
import (
"context"
"database/sql"
"testing"
"time"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
"github.com/testcontainers/testcontainers-go/wait"
_ "github.com/lib/pq" // مشغل PostgreSQL
)
func TestPostgresIntegration(t *testing.T) {
ctx := context.Background()
// 1. تشغيل حاوية PostgreSQL
postgresContainer, err := postgres.RunContainer(ctx,
testcontainers.WithImage("postgres:16-alpine"),
postgres.WithDatabase("testdb"),
postgres.WithUsername("testuser"),
postgres.WithPassword("testpass"),
testcontainers.WithWaitStrategy(
wait.ForLog("database system is ready to accept connections").
WithOccurrence(2).
WithStartupTimeout(60*time.Second)),
)
if err != nil {
t.Fatal(err)
}
defer postgres