اختبار في JavaScript: Unit, Integration, E2E — دليل شامل
جودة الكود هي مفتاح نجاح أي مشروع. في عالم JavaScript (خاصة في Node.js)، أصبح الاختبار ليس مجرد ممارسة جيدة، بل ضرورة. نستعرض ثلاثة مستويات رئيسية: الاختبارات الوحدوية (unit)، والتكاملية (integration)، والشاملة (E2E). ستتعرف على الفروق بينها، ومتى تستخدم كل نوع، وسترى أمثلة عملية باستخدام أدوات شائعة.
1. اختبار Unit: التحقق من الوحدات المعزولة
تتحقق اختبارات Unit من عمل الدوال، أو الكلاسات، أو الوحدات المنفردة بشكل معزول عن الاعتمادات الخارجية (قواعد البيانات، API، نظام الملفات). هذا هو المستوى الأسرع والأكثر موثوقية.
الأدوات والإعداد
الإطار الأكثر شيوعًا هو Jest. التثبيت:
npm install --save-dev jest
أضف السكريبت في package.json:
"scripts": {
"test": "jest"
}
مثال: اختبار دالة حساب الخصم
لننشئ ملف discount.js:
// discount.js
function applyDiscount(price, discountPercent) {
if (price <= 0) throw new Error('Price must be positive');
if (discountPercent < 0 || discountPercent > 100) throw new Error('Invalid discount');
return price - (price * discountPercent) / 100;
}
module.exports = { applyDiscount };
الآن نكتب اختبار Unit في discount.test.js:
const { applyDiscount } = require('./discount');
describe('applyDiscount', () => {
test('calculates 10% discount correctly', () => {
expect(applyDiscount(100, 10)).toBe(90);
});
test('throws error for negative price', () => {
expect(() => applyDiscount(-10, 10)).toThrow('Price must be positive');
});
test('throws error for invalid discount percent', () => {
expect(() => applyDiscount(100, 150)).toThrow('Invalid discount');
});
});
التشغيل: npm test. سيجد Jest تلقائيًا الملفات *.test.js.
نصيحة: استخدم كائنات mock للعزل عن الخدمات الخارجية.
// مثال لمحاكاة API خارجي
jest.mock('./api');
const api = require('./api');
api.getData.mockResolvedValue({ id: 1 });
2. اختبار التكامل: التحقق من تفاعل المكونات
تتحقق اختبارات Integration من كيفية عمل الوحدات المختلفة معًا: قاعدة البيانات + منطق الأعمال + مسارات HTTP. إنها أبطأ من اختبارات unit، لكنها تمنح ثقة أكبر في صحة النظام.
الأدوات: Supertest + Jest
Supertest يسمح بإجراء طلبات HTTP إلى تطبيق Express الخاص بك دون تشغيل الخادم فعليًا.
npm install --save-dev supertest
مثال: اختبار REST API
لنفترض أن لدينا تطبيق Express بسيط app.js:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Missing fields' });
}
// حفظ في قاعدة البيانات (مبسط)
res.status(201).json({ id: 1, name, email });
});
module.exports = app;
اختبار التكامل users.test.js:
const request = require('supertest');
const app = require('./app');
describe('POST /users', () => {
test('creates user with valid data', async () => {
const response = await request(app)
.post('/users')
.send({ name: 'Alice', email: 'alice@test.com' });
expect(response.status).toBe(201);
expect(response.body).toHaveProperty('id');
expect(response.body.name).toBe('Alice');
});
test('returns 400 for missing email', async () => {
const response = await request(app)
.post('/users')
.send({ name: 'Bob' });
```