كيف تشرح للمبرمج أن الخلل ليس مجرد "لا يعمل"؟
\nهل سبق لك أن تلقيت مهمة مثل: "اجعل الزر يعمل بشكل صحيح"؟ أو الأسوأ من ذلك، كتبت كودًا واجتازت الاختبارات، لكن العميل قال: "هذا ليس ما طلبته". ألم مألوف؟ مرحبًا بك في عالم يصبح فيه BDD (التطوير القائم على السلوك) في JavaScript طوق النجاة.
\nBDD ليس مجرد اختصار عصري آخر. إنه نهج يجبر المطورين والمختبرين ومحللي الأعمال على التحدث بلغة واحدة. بلغة روسية حية، بدون "منهجيات" و"نماذج معمارية". اليوم سنشرح كيفية تطبيق BDD في مشروع JavaScript، وسنكتب اختبارات حقيقية، وسنفهم لماذا يجعل هذا الكود أنظف والحياة أسهل.
\n\n\n\n
ما هو BDD وكيف يختلف عن TDD؟
\nدعنا نضع النقاط على الحروف فورًا. BDD (التطوير القائم على السلوك) هو تطور لـ TDD (التطوير القائم على الاختبار). إذا كان TDD يقول: "اكتب الاختبار أولاً، ثم الكود"، فإن BDD يضيف: "لكن يجب أن يكون الاختبار مفهومًا لمستثمر عادي".
\nالفكرة الأساسية لـ BDD: نحن نختبر سلوك النظام، وليس بنيته الداخلية. نحن لا نسأل: "هل ترجع الدالة true؟". نحن نسأل: "هل يمكن للمستخدم إضافة منتج إلى سلة التسوق ورؤية إجمالي الطلب؟". الفرق شاسع.
\nلـ BDD في JavaScript، هناك لغة خاصة — Gherkin. وهي تشبه اللغة الإنجليزية الزائفة (أو الروسية الزائفة) التي تبدو كتعليمات لبناء Lego:
\n\nالوظيفة: سلة التسوق\n كمستخدم مسجل\n أريد إضافة منتجات إلى السلة\n لأرى التكلفة الإجمالية\n\n السيناريو: إضافة منتج واحد\n بافتراض أن المستخدم مسجل الدخول\n عندما يضيف منتج "لابتوب" إلى السلة\n فإن السلة تعرض منتجًا واحدًا\n والتكلفة الإجمالية تساوي 99900 روبل\n\n\nأوافق، هذا يُقرأ كمتطلبات عمل وليس ككود. وهذه هي الميزة الرئيسية لـ BDD.
\n\n\n\n
أدوات BDD في JavaScript
\nلممارسة التطوير القائم على السلوك في JavaScript، تحتاج إلى الأدوات الصحيحة. إليك الأركان الثلاثة التي يقوم عليها كل شيء:
\n\n- \n
- Cucumber.js — الإطار الأكثر شيوعًا لـ BDD. يقوم بتحليل سيناريوهات Gherkin وربطها بالكود. \n
- Jest + Jest-Cucumber — إذا كنت تستخدم Jest بالفعل، فهذا خيار مثالي. لا سحر، فقط تكامل نقي. \n
- Mocha + Chai + Gherkin — لمن يحبون بناء الأشياء يدويًا. مرن، لكنه يتطلب كودًا أكثر. \n
سنستخدم Cucumber.js لأنه المعيار الصناعي. التثبيت بسيط:
\n\nnpm install @cucumber/cucumber --save-dev\n\n\nبعد ذلك، ننشئ مجلد features/ — حيث ستكون ملفات .feature. وفي مجلد step_definitions/ — الكود الذي ينفذ السيناريوهات.
\n\n
نكتب أول اختبار BDD: تسجيل دخول المستخدم
\nلنتخيل أننا نبني متجرًا إلكترونيًا. أول شيء نحتاج لاختباره هو تسجيل الدخول. ننشئ ملف features/login.feature:
# language: ar\nالوظيفة: تسجيل دخول المستخدم\n كزائر للموقع\n أريد الدخول إلى الحساب الشخصي\n لإدارة طلباتي\n\n السيناريو: دخول ناجح ببيانات صحيحة\n بافتراض أنني في صفحة الدخول\n عندما أدخل البريد الإلكتروني "user@example.com" وكلمة المرور "123456"\n وأضغط على زر "دخول"\n فإنني أرى ترحيبًا "مرحبًا، إيفان!"\n\n\nالآن نحتاج لكتابة الخطوات (steps) — كود JavaScript الذي ينفذ هذه الإجراءات. ننشئ step_definitions/login.steps.js:
const { Given, When, Then } = require('@cucumber/cucumber');\nconst { expect } = require('chai');\n\n// حالة التطبيق (محاكاة)\nlet currentPage = '';\nlet userEmail =