الاختبار التكاملي لـ Go مع Docker: دليل خطوة بخطوة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

اختبار التكامل في Go باستخدام Docker: دليل شامل



اختبار التكامل هو مرحلة أساسية في تطوير تطبيقات Go الموثوقة. على عكس اختبارات الوحدة، تتحقق اختبارات التكامل من تفاعل المكونات: قاعدة البيانات، ذاكرة التخزين المؤقت، واجهات برمجة التطبيقات الخارجية. يتيح Docker عزل بيئة الاختبار، مما يجعل الاختبارات قابلة للتكرار ومستقلة عن الجهاز المضيف. في هذه المقالة، سنشرح كيفية إعداد اختبار التكامل لتطبيقات Go باستخدام Docker — من الحاويات البسيطة إلى السيناريوهات المتقدمة مع Testcontainers و CI/CD.



1. لماذا Docker لاختبار التكامل في Go؟



غالبًا ما تعمل تطبيقات Go مع PostgreSQL أو Redis أو MongoDB أو خدمات أخرى. الإعداد اليدوي لهذه التبعيات على كل جهاز مطور وخادم CI هو طريق للأخطاء. يحل Docker هذه المشكلة:

  • قابلية التكرار — نفس البيئة محليًا وفي CI.
  • العزل — الاختبارات لا تلوث النظام المضيف.
  • السرعة — يتم تشغيل الحاويات في ثوانٍ.
  • التوازي — يمكن تشغيل عدة اختبارات معزولة في وقت واحد.


لننظر إلى مثال أساسي: اختبار دالة تحفظ البيانات في PostgreSQL.



2. إعداد بيئة الاختبار باستخدام Docker Compose



لننشئ docker-compose.test.yml لقاعدة بيانات الاختبار:



version: '3.8'services:  postgres_test:    image: postgres:16-alpine    environment:      POSTGRES_USER: test      POSTGRES_PASSWORD: test      POSTGRES_DB: testdb    ports:      - "5433:5432"  # نستخدم منفذًا غير قياسي لتجنب التعارض مع قاعدة البيانات المحلية    tmpfs: /var/lib/postgresql/data  # البيانات في الذاكرة للسرعة


في اختبار Go، نرفع الحاوية عبر os/exec أو نستخدم مكتبة testcontainers-go. سنعرض كلا النهجين.



2.1. تشغيل Docker Compose يدويًا من الاختبار



// main_test.gopackage main

import ( "context" "fmt" "os/exec" "testing" "time")

func setupTestDB(t *testing.T) string { t.Helper() // تشغيل الحاوية cmd := exec.Command("docker-compose", "-f", "docker-compose.test.yml", "up", "-d") if err := cmd.Run(); err != nil { t.Fatalf("فشل تشغيل docker-compose: %v", err) } // انتظار جاهزية PostgreSQL time.Sleep(3 * time.Second) return "postgres://test:test@localhost:5433/testdb?sslmode=disable"}

func TestSaveUser(t *testing.T) { dsn := setupTestDB(t) db, err := sql.Open("postgres", dsn) if err != nil { t.Fatal(err) } defer db.Close() // ... كود الاختبار}


العيوب: sleep يدوي، صعوبة مع الاختبارات المتوازية. من الأفضل استخدام Testcontainers.



2.2. Testcontainers لـ Go



قم بتثبيت المكتبة:

go get github.com/testcontainers/testcontainers-go


مثال مع إدارة تلقائية للحاوية:



// repository_test.gopackage repository

import ( "context" "testing" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" "github.com/jackc/pgx/v5/pgxpool")

func TestUserRepository_Save(t *testing.T) { ctx := context.Background()

// طلب حاوية PostgreSQL req := testcontainers.ContainerRequest{ Image: "postgres:16-alpine", ExposedPorts: []string{"5432/tcp"}, Env: map[string]string{ "POSTGRES_USER": "test", "POSTGRES_PASSWORD": "test", "POSTGRES_DB": "testdb", }, WaitingFor: wait.ForLog("database system is ready to accept connections"), }

postgres, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req

المدونات

توصيات الكتب