وقتی تست ها انعطاف دارند...

پروژه ای رو فرض کنید که نسبتا بزرگ محسوب میشه و دارای تست unit است. در واقع برای عملکرد هر قسمت و متد از سیستم تست unit متناظری نیز وجود داشته باشه.بعد از مدتی نیازمندی مشتری در قسمتی از پروژه تغییر میکنه. اگر فرض را براین بگیریم که به روش ابتدا تست سپس کد (TDD) پایبند هستیم. خب حالا کدام تست ها را باید مطابق با ویژگی جدید محصول تغییر بدهیم؟از آنجایی که تست های unit بر نحوه پیاده سازی کد تمرکز دارد نیاز به refator مداوم دارند و با این حال بدست آوردن خط مشی مشخصی از تست های شده ی مربوط به هر Feature بعد از مدتی کار ساده ای نخواهد بود.اما راه حل؟ بله درسته!‌ میتونیم تست ها را با دید مشتری و براساس نیازمندیهای او بنویسیم.خب برای این کار برگردیم به نحوه بیان مشتری از نیازهاش. مشتری ها عموما اینطوری نیازشون رو بیان میکنن:وقتی کاربر لاگین نکرده کالایی را به سبد خرید اضافه کرد پیغام ابتدا ثبت نام کنید بر روی صفحه نمایش داده شود برای تبدیل این جمله به سراغ زبان gherkin میریم. این زبان از چند قاعده کلی پیروی میکنه که اگه اون ها رو بدونیم میتونیم کارمون رو شروع کنیم ( برای بیشتر دونستن اینجا رو ببنید )Feature, Scenario, Given, When, Thenتوجه کنید که در gherkin فقط این کلمات کلیدی هستند و جملاتی که در مقابل آنها قرار میگیرد در واقع نام متدی است که قرار است تبدیل به تست در زبان مورد نظر شما شود. کافیه یه فایل با پسوند feature ایجاد کنیم.در هر فایل میتوانید یک بار از کلمه Feature استفاده کنید:Feature: add product to cardIn order to add product in cardAs an userI want to get right messageو به ازای هر Feature میتونید Scenario های متعددی بنویسید:Scenario: add product as unauthorized userمفروضات (چیزهایی که برای انجام این تست نیاز داریم داشته باشیم مثل کاربری با مشخصات معین) تست:Given unathorized userحالا رخدادی که کاربر سیستم آنرا انجام میدهد تا نتیجه لازم را بدست بیاورد:When I add product to cardو در پایان نتیجه ای که انتظار داریم:Then I should get message &quotlogin PLZ!!&quotحالا با توجه به زبانی که از اون استفاده میکنید باید **ابزاری** پیدا کنید تا تست gherkin رو به زبان مورد نظرتون تبدیل کنه:من برای php از behat و در python از behave استفاده میکنم و توصیه شون میکنمدر جاوا اسکریپت هم از cucumber استفاده کردم و توصیه ش نمیکنم :)حالا کافیه فایل با پسوند feature به زبان gherkin رو با ابزار مورد نظرتون اجرا کنید:npm run cucumber firsttest.featureخروجی ترمینال شما باید چیزی شبیه به این (مثال javascript) خواهد بود:? Given unathorized userUndefined. Implement with the following snippet:Given('unathorized user', function () {// Write code here that turns the phrase above into concrete actionsreturn 'pending';});? When I add product to cardUndefined. Implement with the following snippet:When('I add product to card', function () {// Write code here that turns the phrase above into concrete actionsreturn 'pending';});? Then I should get message &quotlogin PLZ!!&quotUndefined. Implement with the following snippet:Then('I should get message {string}', function (string) {// Write code here that turns the phrase above into concrete actionsreturn 'pending';});فراموش نکنید که دو شیوه Unit Test و BDD رو در مقابل هم قرار ندید چرا که برای تکمیل یک پروژه هم به نظر مشتری و مدیر محصول نیاز دارید تا بدونید محصول شما در نهایت باید چگونه کار کند؟ و هم برای اینکه دولوپر سنیور شما از قابل نگهداری نوشته شدن تست ها مطمئن بشه به تست های unit نیاز خواهید داشت.احتمالا الان راحت تر میتونید تشخیص بدهید که چطور نوشتن تست BDD ما رو در مقابل تغییر نیاز مشتری ایمن نگه میداره.