لماذا TDD ليس مجرد موضة عابرة، بل هو أفضل صديق جديد لك
\n\nتخيل: أنت تكتب كوداً، كل شيء يعمل بشكل مثالي. تقوم بتشغيل التطبيق - لا توجد أخطاء. بعد أسبوع، تضيف ميزة جديدة... وكل شيء ينهار. هل هذا مألوف؟ إذا كنت قد أمضيت ساعات في البحث عن خطأ ظهر بسبب تغيير عشوائي في وحدة مجاورة - فهذه المقالة لك.
\n\nالتطوير القائم على الاختبار (Test-Driven Development, TDD) ليس مجرد منهجية، بل هو طوق نجاة حقيقي للمطور. في عالم JavaScript، حيث يتغير الكود أسرع من الطقس، يساعدك TDD على البقاء واقفاً على قدميك. دعنا نفهم كيف يعمل هذا، ولماذا بعد TDD لن تتمكن من كتابة الكود بالطريقة القديمة.
\n\nما هو TDD في الحقيقة؟ (تحذير: لا يتعلق الأمر بالاختبارات)
\n\nيعتقد الكثيرون أن TDD هو مجرد "كتابة اختبارات قبل الكود". لكن في الحقيقة هو فلسفة تصميم. TDD يجعلك تفكر في كيفية استخدام الكود الخاص بك، قبل أن تكتبه. إنه مثل مهندس معماري يرسم مخطط المبنى أولاً، ثم يبدأ في البناء.
\n\nتتكون دورة TDD من ثلاث خطوات (غالباً ما تسمى "Red-Green-Refactor"):
\n\n- \n
- Red: اكتب اختباراً سيفشل بالتأكيد (لأن الوظيفة غير موجودة بعد). \n
- Green: اكتب الحد الأدنى من الكود ليجتاز الاختبار. \n
- Refactor: حسّن الكود دون تغيير سلوكه (تضمن الاختبارات أنك لم تكسر شيئاً). \n
ونعم، تتكرر هذه الدورة لكل وحدة صغيرة من الوظائف. يبدو وكأنه تباطؤ؟ ربما. لكن على المدى الطويل، ستوفر ساعات من التصحيح.
\n\nلماذا JavaScript مثالي لـ TDD
\n\nJavaScript هي لغة ديناميكية. هذه هي قوتها وضعفها. الأخطاء في وقت التشغيل أمر شائع، خاصة في المشاريع الكبيرة. TDD يحول JavaScript من أداة "مرنة لكنها هشة" إلى منصة موثوقة.
\n\nعلاوة على ذلك، فإن نظام JS البيئي غني بأدوات الاختبار: Jest، Mocha، Chai، Jasmine. سنستخدم Jest - فهو بسيط وقوي وشائع. إذا لم تكن على دراية بـ Jest بعد، لا تقلق: سنبدأ من الأساسيات.
\n\nتطبيق عملي: كتابة آلة حاسبة باستخدام TDD
\n\nالنظرية جيدة، لكن دعنا ننتقل إلى كود حقيقي. سنكتب آلة حاسبة بسيطة باستخدام TDD. هذا مثال كلاسيكي، لكنه يوضح العملية بشكل ممتاز.
\n\nالخطوة 1: إعداد المشروع
\n\nأنشئ مجلداً جديداً وقم بتهيئة المشروع:
\n\nmkdir tdd-calculator\ncd tdd-calculator\nnpm init -y\nnpm install --save-dev jest\n\n\nأضف السكريبت في package.json:
"scripts": {\n "test": "jest"\n}\n\n\nالخطوة 2: الأحمر - كتابة اختبار لعملية الجمع
\n\nأنشئ ملف calculator.test.js:
// calculator.test.js\nconst { add } = require('./calculator');\n\ndescribe('Calculator', () => {\n test('adds 2 + 3 to equal 5', () => {\n expect(add(2, 3)).toBe(5);\n });\n});\n\n\nشغّل الاختبار: npm test. سيفشل مع خطأ لأن الدالة add غير موجودة. هذا طبيعي - هذه هي المرحلة الحمراء.
الخطوة 3: الأخضر - كتابة الحد الأدنى من الكود
\n\nأنشئ calculator.js:
// calculator.js\nfunction add(a, b) {\n return a + b;\n}\n\nmodule.exports = { add };\n\n\nشغّل الاختبار مرة أخرى. أخضر؟ ممتاز! لقد اجتزنا للتو المرحلة الخضراء.
\n\nالخطوة 4: إعادة الهيكلة (Refactoring)
\n\nالكود بسيط، لا شيء لإعادة هيكلته. لكن تخيل أننا نريد إضافة التحقق من نوع البيانات. TDD يسمح لنا بفعل ذلك بأمان: أولاً اختبار، ثم كود.
\n\n// calculator.test.js\ntest('throws error if arguments are not numbers', () => {\n expect(() => add('2', 3)).toThrow('Arguments must be numbers');\n});\n\n\nالآن نقوم بتعديل add: