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

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

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

ابدأ الدورة

اختبار TypeScript: من الوحدة إلى E2E — دليل شامل

\n

تطوير الويب الحديث لا يمكن تصوره بدون اختبار عالي الجودة. TypeScript، كطبقة فوقية لـ JavaScript، يوفر أدوات قوية للكتابة (Typing)، لكنه لا يحل مشكلة الأخطاء المنطقية. في هذه المقالة، سنستعرض ثلاثة مستويات من الاختبار: unit (اختبار الوحدة)، integration (اختبار التكامل)، وe2e (اختبار شامل). ستتعلم كيفية إعداد البيئة، وكتابة اختبارات فعالة بلغة TypeScript، ودمجها في خط أنابيب CI/CD.

\n\n

1. اختبار الوحدة: أساس هرم الاختبار

\n

تتحقق اختبارات الوحدة من الوحدات المنعزلة (الدوال، الفئات، الطرق) دون الاعتماد على التبعيات الخارجية. أفضل خيار لـ TypeScript هو Jest — فهو يدعم TypeScript بشكل افتراضي ويوفر واجهة برمجة تطبيقات غنية للـ mocks والـ assertions.

\n\n

إعداد Jest لـ TypeScript

\n
npm install --save-dev jest @types/jest ts-jest\nnpx ts-jest config:init
\n

يجب أن يحتوي ملف jest.config.ts على:

\n
export default {\n  preset: 'ts-jest',\n  testEnvironment: 'node',\n  roots: ['<rootDir>/src'],\n  testMatch: ['**/__tests__/**/*.test.ts']\n};
\n\n

مثال لاختبار وحدة لدالة

\n

لنفترض أن لدينا دالة لحساب الخصم:

\n
// src/utils/discount.ts\nexport function calculateDiscount(price: number, percent: number): number {\n  if (percent < 0 || percent > 100) throw new Error('Invalid percent');\n  return price - (price * percent) / 100;\n}
\n

اختبارها:

\n
// src/__tests__/discount.test.ts\nimport { calculateDiscount } from '../utils/discount';\n\ndescribe('calculateDiscount', () => {\n  it('يجب أن يعيد 80 لسعر 100 وخصم 20%', () => {\n    expect(calculateDiscount(100, 20)).toBe(80);\n  });\n\n  it('يجب أن يرمي خطأ عند نسبة مئوية غير صحيحة', () => {\n    expect(() => calculateDiscount(100, 150)).toThrow('Invalid percent');\n  });\n\n  it('يجب أن يعيد 0 عند خصم 100%', () => {\n    expect(calculateDiscount(50, 100)).toBe(0);\n  });\n});
\n\n

العمل مع الـ Mocks

\n

لعزل الاختبارات، استخدم الـ mocks. مثال مع خدمة تعتمد على قاعدة البيانات:

\n
// src/services/user.service.ts\nimport { db } from '../database';\n\nexport class UserService {\n  async getUser(id: number) {\n    const user = await db.findUser(id);\n    if (!user) throw new Error('User not found');\n    return user;\n  }\n}
\n
// src/__tests__/user.service.test.ts\nimport { UserService } from '../services/user.service';\nimport { db } from '../database';\n\njest.mock('../database');\n\ndescribe('UserService', () => {\n  it('يجب أن يعيد المستخدم', async () => {\n    const mockUser = { id: 1, name: 'Alice' };\n    (db.findUser as jest.Mock).mockResolvedValue(mockUser);\n\n    const service = new UserService();\n    const result = await service.getUser(1);\n    expect(result).toEqual(mockUser);\n  });\n});
\n\n

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

\n

تتحقق اختبارات التكامل من كيفية عمل الوحدات معًا: مسارات API، قواعد البيانات، الخدمات الخارجية. لتطبيقات TypeScript على Node.js، غالبًا ما يُستخدم Supertest مع Jest.

\n\n

إعداد اختبار التكامل لـ Express/NestJS

\n
npm install --save-dev supertest @types/supertest
\n

مثال لاختبار REST API (NestJS):

\n
// src/__tests__/app.integration.test.ts\nimport { Test, TestingModule } from '@nestjs/testing';\nimport { INestApplication } from '@nestjs/common';\nimport * as request from 'supertest';\nimport { AppModule } from '../app.module';\n\ndescribe('AppController (e2e)', () => {\n  let app: INestApplication;\n\n  beforeAll(async () => {\n    const moduleFixture: TestingModule = await Test.createTestingModule({\n      imports: [AppModule],\n    }).compile();\n\n    a                

المدونات

توصيات الكتب