الاختبار الشامل من البداية إلى النهاية (E2E)
الاختبار الشامل من البداية إلى النهاية (E2E)
يُشغّل الاختبار الشامل (E2E) تطبيق NestJS بالكامل داخل بيئة الاختبار، ويُرسل طلبات HTTP حقيقية عبره، للتحقّق من أنّ كل طبقة — التوجيه، والحُرّاس، والأنابيب، والخدمات، وقاعدة البيانات — تعمل معًا بشكل صحيح. على خلاف اختبارات الوحدة التي تعزل فئةً واحدة، تمنحك اختبارات E2E ثقةً بأنّ التطبيق المترابط يتصرّف بشكل صحيح من منظور العالم الخارجي.
الأدوات: Supertest + Jest
يوفّر سقالة NestJS مجلد test/ مع إعداد E2E جاهز. القطعتان الأساسيتان هما:
- Supertest — مكتبة تأكيد HTTP سلسة. تقبل خادم HTTP لـ Express (أو Fastify) وتتيح إجراء طلبات والتأكيد على رموز الحالة والترويسات والأجسام دون الارتباط بمنفذ حقيقي.
- Jest — منفّذ الاختبار. يتضمّن NestJS إعدادًا منفصلًا
jest-e2eفيpackage.jsonيضبطrootDirعلىtest/وtestRegexعلى.e2e-spec.ts.
npm run test:e2e. يستدعي هذا jest --config ./test/jest-e2e.json، وهو منفصل عن تشغيل اختبارات الوحدة (npm test). أبقِ الحزمتين منفصلتين حتى لا تُبطّئ إعدادات قاعدة البيانات اختبارات الوحدة السريعة.
تشغيل التطبيق الكامل في وحدة اختبار
استخدم Test.createTestingModule() — نفس واجهة برمجة اختبارات الوحدة — لكن استورد AppModule الحقيقية بدلًا من شريحة صغيرة. استدعاء .compile() ثم app.init() يُشغّل دورة حياة NestJS (تهيئة الوحدة، خطّافات onApplicationBootstrap، وما إلى ذلك):
main.ts يُسجّل ValidationPipe أو CORS أو بادئة عالمية، فطبّق نفس الإعداد داخل beforeAll. نسيان هذا يجعل الاختبارات تنجح محليًا لكنّها تفشل مقابل التطبيق الحقيقي.
إعداد قاعدة بيانات الاختبار وتنظيفها
إجراء اختبارات E2E على قاعدة البيانات الإنتاجية أو التطويرية أمر خطير. النهج القياسي هو توجيه تشغيل الاختبار إلى قاعدة بيانات اختبار مخصّصة عبر متغيّرات البيئة، ثم التنظيف بعد كل اختبار أو مجموعة:
- اضبط
NODE_ENV=testوأنشئ ملف.env.test(أو استخدم إعداد TypeORM منفصل) يستهدف قاعدة بيانات اختبار فقط أو قاعدة بيانات SQLite في الذاكرة. - شغّل الترحيلات قبل بدء المجموعة (أو استخدم
synchronize: trueللاختبارات فقط). - اقتطع أو أعِد تراجع البيانات بين الاختبارات لتجنّب الإخفاقات المعتمدة على الترتيب.
اختبار نقاط النهاية المحميّة بالمصادقة من البداية إلى النهاية
يتضمّن تدفّق مصادقة E2E الكامل عادةً مرحلتين: الحصول على رمز، ثم استخدامه. تجعل سلاسل Supertest هذا مقروءًا:
ما يجب التأكيد عليه
- رموز الحالة — الفحص الأساسي؛
.expect(200)،.expect(401)،.expect(422). - شكل الاستجابة — تأكّد من وجود الحقول المطلوبة وامتلاكها للأنواع المتوقّعة.
- الآثار الجانبية — بعد POST يُنشئ موردًا، استعلِم قاعدة البيانات مباشرةً (عبر المستودع المحقون) للتأكّد من استمرار الصف.
- تطبيق الحُرّاس — أضِف دائمًا اختبارًا سلبيًا: ضرب مسار محمي بدون رمز يجب أن يُعيد 401.
describe) بياناته الأوّليّة المطلوبة وينظّفها بعد ذلك. الاختبارات التي تعتمد على تشغيل اختبارات سابقة أولًا هشّة وصعبة التصحيح.
الخلاصة
تستخدم اختبارات E2E في NestJS الدالة Test.createTestingModule() مع AppModule الحقيقية وSupertest لإطلاق طلبات HTTP على التطبيق الجاري. وجّه الاختبارات إلى قاعدة بيانات اختبار مخصّصة، وشغّل الترحيلات في beforeAll، ونظّف في afterAll. للمسارات المحميّة بالمصادقة، احصل على JWT في خطوة إعداد ثم أرفِقه عبر ترويسة Authorization. أضِف دائمًا اختبارات سلبية (بدون رمز → 401) وتحقّق من آثار قاعدة البيانات الجانبية لنقاط نهاية الطفرة.