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

پروژه ای رو فرض کنید که نسبتا بزرگ محسوب میشه و دارای تست unit است. در واقع برای عملکرد هر قسمت و متد از سیستم تست unit متناظری نیز وجود داشته باشه.

بعد از مدتی نیازمندی مشتری در قسمتی از پروژه تغییر میکنه. اگر فرض را براین بگیریم که به روش ابتدا تست سپس کد (TDD) پایبند هستیم. خب حالا کدام تست ها را باید مطابق با ویژگی جدید محصول تغییر بدهیم؟

از آنجایی که تست های unit بر نحوه پیاده سازی کد تمرکز دارد نیاز به refator مداوم دارند و با این حال بدست آوردن خط مشی مشخصی از تست های شده ی مربوط به هر Feature بعد از مدتی کار ساده ای نخواهد بود.

اما راه حل؟ بله درسته!‌ میتونیم تست ها را با دید مشتری و براساس نیازمندیهای او بنویسیم.

خب برای این کار برگردیم به نحوه بیان مشتری از نیازهاش. مشتری ها عموما اینطوری نیازشون رو بیان میکنن:

وقتی کاربر لاگین نکرده کالایی را به سبد خرید اضافه کرد پیغام ابتدا ثبت نام کنید بر روی صفحه نمایش داده شود

برای تبدیل این جمله به سراغ زبان gherkin میریم. این زبان از چند قاعده کلی پیروی میکنه که اگه اون ها رو بدونیم میتونیم کارمون رو شروع کنیم ( برای بیشتر دونستن اینجا رو ببنید )

Feature, Scenario, Given, When, Then

توجه کنید که در gherkin فقط این کلمات کلیدی هستند و جملاتی که در مقابل آنها قرار میگیرد در واقع نام متدی است که قرار است تبدیل به تست در زبان مورد نظر شما شود. کافیه یه فایل با پسوند feature ایجاد کنیم.

در هر فایل میتوانید یک بار از کلمه Feature استفاده کنید:

Feature: add product to card
In order to add product in card
As an user
I 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 "login PLZ!!"

حالا با توجه به زبانی که از اون استفاده میکنید باید **ابزاری** پیدا کنید تا تست gherkin رو به زبان مورد نظرتون تبدیل کنه:

من برای php از behat و در python از behave استفاده میکنم و توصیه شون میکنم

در جاوا اسکریپت هم از cucumber استفاده کردم و توصیه ش نمیکنم :)

حالا کافیه فایل با پسوند feature به زبان gherkin رو با ابزار مورد نظرتون اجرا کنید:

npm run cucumber firsttest.feature

خروجی ترمینال شما باید چیزی شبیه به این (مثال javascript) خواهد بود:

? Given unathorized user
Undefined. Implement with the following snippet:
Given('unathorized user', function () {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
? When I add product to card
Undefined. Implement with the following snippet:
When('I add product to card', function () {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
? Then I should get message "login PLZ!!"
Undefined. Implement with the following snippet:
Then('I should get message {string}', function (string) {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});

فراموش نکنید که دو شیوه Unit Test و BDD رو در مقابل هم قرار ندید چرا که برای تکمیل یک پروژه هم به نظر مشتری و مدیر محصول نیاز دارید تا بدونید محصول شما در نهایت باید چگونه کار کند؟ و هم برای اینکه دولوپر سنیور شما از قابل نگهداری نوشته شدن تست ها مطمئن بشه به تست های unit نیاز خواهید داشت.

احتمالا الان راحت تر میتونید تشخیص بدهید که چطور نوشتن تست BDD ما رو در مقابل تغییر نیاز مشتری ایمن نگه میداره.