اختبار JavaScript: من الوحدات إلى التكامل والنهاية إلى النهاية (E2E) من الألف إلى الياء

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

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

ابدأ الدورة

اختبار JavaScript: من اختبارات الوحدات إلى الاختبارات الشاملة

\n\n

الاختبار عالي الجودة هو جزء لا يتجزأ من التطوير الاحترافي باستخدام JavaScript. في هذه المقالة، سنناقش المستويات الثلاثة الرئيسية للاختبار: اختبارات الوحدات (unit)، واختبارات التكامل (integration)، واختبارات النهاية إلى النهاية (e2e). ستتعرف على الأدوات التي يجب استخدامها، وكيفية كتابة الاختبارات على Node.js، وكيفية بناء استراتيجية اختبار فعالة.

\n\n

1. اختبار الوحدات (Unit Testing): أساس هرم الاختبار

\n\n

تتحقق اختبارات الوحدات من الوحدات المعزولة - الدوال أو الفئات أو الطرق الفردية. القاعدة الأساسية: يجب ألا يعتمد الكود الذي يتم اختباره على الموارد الخارجية (قواعد البيانات، واجهات API، نظام الملفات).

\n\n

أدوات اختبار الوحدات

\n
    \n
  • Jest - الإطار الأكثر شيوعًا من Facebook. يتضمن بشكل افتراضي mock، snapshots، وتغطية الكود.
  • \n
  • Mocha + Chai - مجموعة مرنة لمن يحبون تخصيص كل شيء يدويًا.
  • \n
  • Vitest - بديل حديث لـ Jest، محسّن لمشاريع Vite.
  • \n
\n\n
// مثال على اختبار وحدة باستخدام Jest\nconst { calculateDiscount } = require('./pricing');\n\ndescribe('calculateDiscount', () => {\n  test('يعيد خصم 10% للمبلغ > 1000', () => {\n    const result = calculateDiscount(1500);\n    expect(result).toBe(1350);\n  });\n\n  test('لا يطبق خصم للمبلغ <= 1000', () => {\n    const result = calculateDiscount(500);\n    expect(result).toBe(500);\n  });\n\n  test('يعالج القيمة الحدية 1000', () => {\n    const result = calculateDiscount(1000);\n    expect(result).toBe(1000);\n  });\n});
\n\n

أفضل ممارسات اختبار الوحدات

\n
    \n
  • اختبر سلوكًا واحدًا في كل مرة (assertion واحد لكل اختبار).
  • \n
  • استخدم أسماء اختبار وصفية (given/when/then).
  • \n
  • تجنب اختبار الطرق الخاصة - اختبر الواجهة العامة.
  • \n
  • حافظ على تغطية الكود عند مستوى 70-80%.
  • \n
\n\n

2. اختبار التكامل (Integration Testing): التحقق من تفاعل المكونات

\n\n

تتحقق اختبارات التكامل من كيفية عمل الوحدات المختلفة معًا. في سياق Node.js، يعني هذا عادةً الاختبار مع قاعدة بيانات حقيقية، أو نظام ملفات، أو واجهات API خارجية.

\n\n

سيناريوهات اختبار التكامل النموذجية

\n
    \n
  • تفاعل المتحكم (controller) مع طبقة الخدمات وقاعدة البيانات.
  • \n
  • التحقق من middleware ومسارات Express/Koa.
  • \n
  • اختبار المستودعات (repositories) مع قاعدة بيانات اختبارية (SQLite في الذاكرة أو PostgreSQL في Docker).
  • \n
\n\n
// مثال على اختبار تكامل باستخدام Supertest و Jest\nconst request = require('supertest');\nconst app = require('../app');\nconst { createTestUser, cleanDatabase } = require('./helpers');\n\nbeforeEach(async () => {\n  await cleanDatabase();\n});\n\ndescribe('POST /api/users', () => {\n  test('ينشئ مستخدمًا ويعيد 201', async () => {\n    const response = await request(app)\n      .post('/api/users')\n      .send({ name: 'إيفان', email: 'ivan@test.com' });\n\n    expect(response.status).toBe(201);\n    expect(response.body).toHaveProperty('id');\n    expect(response.body.name).toBe('إيفان');\n  });\n\n  test('يعيد 400 عند تكرار البريد الإلكتروني', async () => {\n    await createTestUser({ email: 'ivan@test.com' });\n\n    const response = await request(app)\n      .post('/api/users')\n      .send({ name: 'بيتر', email: 'ivan@test.com' });\n\n    expect(response.status).toBe(400);\n    expect(response.body.error).toBe('البريد الإلكتروني مستخدم بالفعل');\n  });\n});
\n\n

إعداد البنية التحتية للاختبار

\n
    \n
  • Docker Compose - لتشغيل خدمات الاختبار (قواعد البيانات، Redis).
  • \n
  • Testcontainers - إدارة برمجية للحاويات من داخل الاختبارات.
  • \n
  • قواعد البيانات في الذاكرة (مثل mongodb-memory-server) - لاختبارات سريعة بدون تبعيات خارجية.
  • \n
\n\n

3. اختبار E2E (النهاية إلى النهاية): التحقق من النظام بأكمله

المدونات

توصيات الكتب