الاختبار في جافاسكريبت: اختبارات الوحدة والتكامل واختبارات E2E
يعد الاختبار جزءًا لا يتجزأ من تطوير أي برنامج عالي الجودة. في عالم جافاسكريبت (خاصة في بيئة Node.js)، هناك ثلاثة مستويات رئيسية للاختبار: اختبارات الوحدة واختبارات التكامل واختبارات E2E (من البداية إلى النهاية). كل منها يحل مهامه الخاصة ويُستخدم في مراحل مختلفة من التطوير. في هذه المقالة، سنحلل كل نوع، ونعرض أمثلة على الكود، ونقدم توصيات عملية.
1. اختبارات الوحدة
اختبارات الوحدة تتحقق من وحدات كود فردية ومعزولة — الدوال، الطرق أو الفئات. الهدف الرئيسي هو التأكد من أن كل "وحدة" تعمل بشكل صحيح بغض النظر عن بقية النظام. في Node.js، غالبًا ما تُستخدم أطر العمل Jest أو Mocha مع Chai لهذا الغرض.
مثال على اختبار وحدة باستخدام Jest
لنفترض أن لدينا دالة بسيطة لحساب الخصم:
// discount.jsfunction calculateDiscount(price, percent) { if (typeof price !== 'number' || typeof percent !== 'number') { throw new Error('Both arguments must be numbers'); } if (price < 0 || percent < 0 || percent > 100) { throw new Error('Invalid values'); } return price - (price * percent / 100);}
module.exports = calculateDiscount;اختبار لهذه الدالة:
// discount.test.jsconst calculateDiscount = require('./discount');
describe('calculateDiscount', () => { test('correctly calculates 10% discount from 1000', () => { expect(calculateDiscount(1000, 10)).toBe(900); });
test('returns 0 at 100% discount', () => { expect(calculateDiscount(500, 100)).toBe(0); });
test('throws an error with a negative price', () => { expect(() => calculateDiscount(-100, 10)).toThrow('Invalid values'); });
test('throws an error with non-numeric arguments', () => { expect(() => calculateDiscount('100', 10)).toThrow('Both arguments must be numbers'); });});- المزايا: سريعة وسهلة الكتابة وتحدد بدقة الوحدة التي بها مشكلة.
- العيوب: لا تتحقق من التفاعل بين المكونات.
- متى تُستخدم: لدوال منطق الأعمال، الأدوات المساعدة، المدققات.
2. اختبارات التكامل
اختبارات التكامل تتحقق من كيفية عمل الوحدات أو الخدمات المختلفة معًا. على سبيل المثال، التفاعل مع قاعدة بيانات، API خارجي أو نظام الملفات. في Node.js، غالبًا ما يُستخدم Supertest (لطلبات HTTP) و Jest لمثل هذه الاختبارات.
مثال على اختبار تكامل لتطبيق Express
لنفترض أن لدينا خادم Express بسيط مع نقطة نهاية لإنشاء مستخدم:
// server.jsconst express = require('express');const app = express();app.use(express.json());
const users = [];
app.post('/users', (req, res) => { const { name, email } = req.body; if (!name || !email) { return res.status(400).json({ error: 'Name and email are required' }); } const user = { id: users.length + 1, name, email }; users.push(user); res.status(201).json(user);});
module.exports = app;اختبار التكامل باستخدام Supertest:
// server.test.jsconst request = require('supertest');const app = require('./server');
describe('POST /users', () => { test('creates a new user with valid data', async () => { const response = await request(app) .post('/users') .send({ name: 'Ivan', email: 'ivan@example.com' });
expect(response.statusCode).toBe(201); expect(response.body).toHaveProperty('id'); expect(response.bo