اختبار E2E لتطبيقات Go: من الفكرة إلى النشر بدون أخطاء

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

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

ابدأ الدورة

لماذا اختبار E2E هو بوليصة التأمين الخاصة بك

\n\n

تخيل: لقد كتبت خدمة مصغرة رائعة بلغة Go. اختبارات الوحدة خضراء، واختبارات التكامل أيضًا. تنشرها في الإنتاج، و... يشتكي المستخدمون من أن سلة التسوق لا تُفرغ بعد الدفع. مألوف؟ المشكلة هي أن اختبار E2E لتطبيقات Go غالبًا ما يُؤجل "لوقت لاحق". وهذا خطأ.

\n\n

الاختبارات الشاملة (End-to-End) هي الطريقة الوحيدة للتحقق من أن نظامك يعمل كوحدة متكاملة: من طلب HTTP إلى الكتابة في قاعدة البيانات والعودة. في هذه المقالة، لن نتحدث فقط عن النظرية - سأريكم أمثلة كود حقيقية بلغة Go يمكنكم نسخها وتشغيلها اليوم.

\n\n

ما هو اختبار E2E في سياق Golang؟

\n\n

اختبار E2E في Go هو التحقق من سيناريو المستخدم الكامل: بدء التطبيق، تنفيذ منطق الأعمال، التفاعل مع الخدمات الخارجية (قواعد البيانات، التخزين المؤقت، قوائم الانتظار) والتحقق من النتيجة. على عكس اختبارات الوحدة، نحن لا نستخدم mock لقاعدة البيانات - بل نقوم بتشغيل PostgreSQL حقيقي في حاوية.

\n\n

كيف يختلف E2E عن اختبارات التكامل؟

\n\n

غالبًا ما يتم الخلط بين هذه المفاهيم. دعنا نوضح الأمور:

\n\n
    \n
  • اختبارات الوحدة - تختبر دالة واحدة. سريعة ومعزولة.
  • \n
  • اختبارات التكامل - تختبر ربط الوحدات (مثل: المستودع + قاعدة البيانات).
  • \n
  • اختبارات E2E - تشغل التطبيق بأكمله وتحاكي إجراءات المستخدم الحقيقي.
  • \n
\n\n

لـ الاختبار الشامل في Golang سنستخدم الحزمة القياسية testing بالإضافة إلى أدوات قوية: testcontainers-go و dockertest.

\n\n

إعداد البيئة: Docker Compose و Testcontainers

\n\n

أسهل طريقة لتنظيم اختبار e2e في go هي استخدام Docker. لديك طريقتان:

\n\n

الخيار 1: Docker Compose (لـ CI/CD)

\n\n

أنشئ ملف docker-compose.test.yml:

\n\n
version: '3.8'\nservices:\n  db:\n    image: postgres:15-alpine\n    environment:\n      POSTGRES_DB: testdb\n      POSTGRES_USER: test\n      POSTGRES_PASSWORD: test\n    ports:\n      - "5432:5432"\n  \n  app:\n    build: .\n    depends_on:\n      - db\n    environment:\n      DATABASE_URL: "postgres://test:test@db:5432/testdb?sslmode=disable"\n    ports:\n      - "8080:8080"\n
\n\n

الخيار 2: Testcontainers (للتطوير المحلي)

\n\n

مكتبة testcontainers-go تسمح بتشغيل الحاويات مباشرة من الاختبارات. هذا هو المفضل لدي - الاختبارات تدير البنية التحتية بنفسها.

\n\n
// setup_test.go\npackage e2e_test\n\nimport (\n    "context"\n    "testing"\n    "time"\n\n    "github.com/testcontainers/testcontainers-go"\n    "github.com/testcontainers/testcontainers-go/wait"\n)\n\nfunc setupPostgres(t *testing.T) string {\n    t.Helper()\n    \n    ctx := context.Background()\n    \n    req := testcontainers.ContainerRequest{\n        Image:        "postgres:15-alpine",\n        ExposedPorts: []string{"5432/tcp"},\n        Env: map[string]string{\n            "POSTGRES_DB":       "testdb",\n            "POSTGRES_USER":     "test",\n            "POSTGRES_PASSWORD": "test",\n        },\n        WaitingFor: wait.ForLog("database system is ready to accept connections").\n            WithStartupTimeout(30 * time.Second),\n    }\n    \n    container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{\n        ContainerRequest: req,\n        Started:          true,\n    })\n    if err != nil {\n        t.Fatalf("failed to start container: %v", err)\n    }\n    \n    t.Cleanup(func() {\n        container.Terminate(ctx)\n    })\n    \n    host, _ := container.Host(ctx)\n    port, _ := container.MappedPort(ctx, "5432")\n    \n    return "postgres://test:test@" + host + ":" + port.Port() + "/testdb?sslmode=disable"\n}\n
\n\n

كتابة أول اختبار E2E لخادم HTTP

المدونات

توصيات الكتب