BDD على TypeScript: عندما يتحدث الكود بلغة العمل
\n\nهل سبق لك أن ترجمت مستندًا متعدد الصفحات من المتطلبات، لتكتشف أن العميل كان يقصد شيئًا مختلفًا تمامًا؟ هل تعرف الموقف عندما ينظر المطور والمحلل إلى نفس المهمة، لكن كل منهما يرى تطبيقًا مختلفًا؟ إذا كان الأمر كذلك، فأنت ناضج لاستخدام BDD (التطوير القائم على السلوك) — المنهجية التي تزيل الحدود بين "أريد" و"تم".
\n\nاليوم سنتحدث عن كيفية تطبيق BDD على TypeScript. سأوضح لك كيفية تحويل المواصفات المملة إلى سيناريوهات حية وقابلة للتنفيذ، يفهمها كل من المدير ومطور الواجهة الخلفية. هذا ليس مجرد اختبارات — إنها لغة مشتركة للفريق.
\n\nبالمناسبة، إذا كنت في بداية رحلتك مع TypeScript، أنصحك بإلقاء نظرة على قاعدة معرفة PythonLib — فهناك مواد ممتازة عن الأساسيات. ونحن نواصل.
\n\nما هو BDD ولماذا تحتاجه؟
\n\nالتطوير القائم على السلوك هو تطور لـ TDD (التطوير القائم على الاختبار). إذا كان TDD يركز على "كيف" يعمل الكود (تُكتب الاختبارات قبل التنفيذ)، فإن BDD يجيب على سؤال "ماذا" يجب أن يفعل النظام من وجهة نظر المستخدم.
\n\nالميزة الرئيسية لـ BDD هي صياغة Gherkin. إنها بنية "بفرض — عندما — حينئذ" (Given — When — Then)، والتي تبدو كالتالي:
\n\nالوظيفة: تسجيل دخول المستخدم\n كمستخدم مسجل\n أريد تسجيل الدخول إلى النظام\n للوصول إلى لوحة التحكم الشخصية\n\n السيناريو: تسجيل دخول ناجح\n بفرض مستخدم بالبريد الإلكتروني "test@example.com" وكلمة المرور "123456"\n عندما يدخل المستخدم بيانات صحيحة\n حينئذ يقوم النظام بتوجيهه إلى لوحة التحكم الشخصية\n\n\nألا توافق أن هذا أوضح من "اختبار الوحدة يتحقق من أن الدالة login() ترجع true"؟ هذه هي قوة BDD: اختبارات TypeScript تصبح وثائق يمكن لأي عضو في الفريق قراءتها.
\n\nمتى يكون BDD مجديًا؟
\n\n- \n
- منطق الأعمال المعقد — عندما يحتوي الكود على العديد من الشروط وسلاسل الإجراءات وسيناريوهات الأخطاء. \n
- الفرق الموزعة — محللون في موسكو، مطورون في مينسك، مختبرون في نوفوسيبيرسك. BDD هي لغتهم المشتركة. \n
- الخدمات المصغرة — عندما تحتاج إلى وصف عقود التفاعل بين الخدمات بوضوح. \n
أدوات BDD على TypeScript
\n\nلتطبيق BDD في TypeScript لدينا أداتان رئيسيتان: Cucumber.js (أو متغيراته) وJest مع الإضافات. دعنا نستعرض كلا النهجين.
\n\nCucumber.js + TypeScript: الكلاسيكي
\n\nCucumber هو المعيار الذهبي لـ BDD. يقرأ ملفات Gherkin (عادةً بامتداد .feature) ويشغل كود الخطوات الذي تكتبه بـ TypeScript.
التثبيت:
\n\nnpm install --save-dev @cucumber/cucumber typescript ts-node\nnpm install --save-dev @types/node\n\n\nننشئ ملف features/login.feature:
الوظيفة: تسجيل الدخول إلى النظام\n كمستخدم\n أريد تسجيل الدخول\n للوصول إلى الوظائف\n\n السيناريو: تسجيل دخول ناجح بالبريد الإلكتروني وكلمة المرور الصحيحين\n بفرض أنني أفتح صفحة تسجيل الدخول\n عندما أدخل البريد الإلكتروني "admin@test.com"\n وأدخل كلمة المرور "secret"\n وأضغط على زر "تسجيل الدخول"\n حينئذ أرى رسالة الترحيب "مرحبًا، Admin!"\n\n\nالآن نكتب الخطوات بـ TypeScript. ننشئ features/step_definitions/login.steps.ts:
import { Given, When, Then } from '@cucumber/cucumber';\nimport { expect } from 'chai';\n\n// محاكاة بسيطة لحالة التطبيق\nconst appState = {\n currentPage: '',\n loggedInUser: ''\n};\n\nGiven('أفتح صفحة تسجيل الدخول', function () {\n appState.currentPage = 'login';\n appState.loggedInUser = '';\n});\n\nWhen('أدخل البريد الإلكتروني {string}', function (email