توسعه اپلیکیشن های React بصورت TDD - قسمت دوم

در قسمت اول مقاله خیلی کوتاه و با یک مقدمه ساده در مورد TDD صحبت کردیم که اصلا چی هستش و چه مزیت مهمی رو برای توسعه نرم افزار داره. بهتون jest و enzyme رو معرفی کردم و گفتم که اول باید jest رو نصب کنید و بعدش برای تست کدهای react به enzyme احتیاج دارید که یک نوع utility بحساب میادش.

تو قسمت دوم می خوام کمی بیشتر در مورد TDD و مراحلش صحبت کنم و البته استارت یادگیری jest و اینکه چجوری باهاش تست بنویسیم رو داشته باشیم.

برنامه نویسی تست محور در React
برنامه نویسی تست محور در React
توجه : برای نوشتن تست های مورد نظر در خصوص پروژه های React اول باید jest رو بفهمید و یاد بگیرید کلا تست نوشتن چجوری هستش و بعد بریم سراغ Enzyme و تست های مربوط به خود React

البته اگر به Wikipedia سر بزنید و TDD رو سرچ کنید , تمام توضیحات و مراحل بصورت خلاصه وجود داره , ولی چون قصد این سری مقالات آموزش از پایه به زبان فارسی هستش قرار نیست خواننده رو از پاس دادن به مقالات و توضیحات انگلیسی گمراه کنیم و همینجا قراره همه چیز تا حد ممکن نوشته بشه تا شما با بهترین نحو متوجه بشید و مثال های مربوطه رو هم دقیق بررسی کنید ...

توجه : همانطورکه قبلا هم گفتم TDD یک مفهوم مهم در روال توسعه نرم افزار هستش و یکمی حرفه ای بحساب میاد و البته شاید برنامه نویس های آماتور و مبتدی در شروع کار این قضیه رو بخوان بفهمن براشون سخت و گنگ بنظر برسه , من پیشنهاد می کنم اول در حوزه کاری خودتون مثلا React یا PHP حتی , به یک حد قابل قبول و درک کلی برسید و بعد بیاید سراغ TDD که کمتر گمراه بشید و خدایی نکرده از کدنویسی زده نشید و مرحله به مرحله جلو برید ...
مراحل توسعه تست محور TDD
مراحل توسعه تست محور TDD


مراحل توسعه تست محور یا TDD چیست ؟

در این بخش به مراحل توسعه تست محور و یا Test Driven Development اشاره می کنیم :

مرحله اول - نوشتن یک تست : در این مرحله ما حتی یک خط کد هم نمی نویسیم و هیچ تابع , کلاس , متغیر یا کد عملیاتی نداریم. یعنی برای شروع هر feature از برنامه اول باید تست اون رو بنویسیم. در این مرحله لازمه که برنامه نویس به نوشتن unit-test ها آشنایی داشته باشه و بدونه چی به چی هست و تست های
مورد نظر چجوری و از کجا میان.

مرحله دوم - اجرای تست ها : بعد از اینکه در مرحله اول تست هارو نوشتیم اینبار اجراشون می کنیم که ببینیم آیا test-framework داره درست کار می کنه و بدون ورود کدهای برنامه تست هارو pass نمی کنه یا اینکه ایرادی این وسط هستش.

مرحله سوم - نوشتن کدها : در این مرحله کدهای ساختار اون بخش یا feature رو می نویسیم که بتونه تست های مربوطه رو pass کنه. در اینجا شاید اشکالاتی در نوشتن کد یا مرتب نبودنش هم باشه ولی در 2 مرحله بعد این مشکلات رو حل می کنیم و منظم میشن.

مرحله چهارم - اجرای مجدد تست : بعد از اینکه کدهارو نوشتیم و ساختار کد ایجاد شد حالا دوباره تست هارو اجرا می کنیم که ببینیم pass میشن یا نه. اگر اوکی بود که میریم مرحله بعد و اگر نه باید ویرایش کدهارو در این مرحله انجام و تست دوباره تکرار بشه.

مرحله پنجم - ویرایش اصولی کد یا Refactor : تو مرحله سوم گفتیم که اگر اشکالات اصولی باشه باید تو دو مرحله بعد یعنی همین Refactor انجام بدیم. اینجا کد رو cleaned-up باید تحویل بدیم و خروجی بهینه و بر اساس قاعده کدنویسی داشته باشیم.

تا اینجا یک مرحله ساده و خوب از TDD رو باهاش آشنا شدیم و پایه تمام روش های پیاده سازی TDD روی همین 5 یا بعضا 6 مرحله طی میشه و لازمه باهاش آشنایی داشته باشید و با کدنویسی روی همچین فرهنگی و اصولی مسلط بشید.

بازم تاکید می کنم که TDD یک روش حرفه ای در پیاده سازی نرم افزار هستش و برای تیم های خیلی اصولی و حرفه ای پیشنهاد میشه , اگر پروژه کوچیک و حتی کمی بزرگ دارید که با روش معمولی و بدون TDD کد می نویسید مایوس نشید و انشاءالله مرحله به مرحله با تلاش , تمرین و مطالعه بیشتر بیاید روی همچین روشی و کدهای حرفه ای و اصولی تری بنویسید.

خوب حالا با مراحل آشنا شدیم و بیایم با ابزار jest آشنا بشیم.

پکیج یا ابزار jest framework چیست ؟

برای تست کدهای جاوااسکریپت ابزار یا framework های دیگه هم مثل Mocha وجود داره ولی من خودم این آموزش هارو با jest جلو می برم. در حقیقت testing framework ها این امکان رو به ما میدن که همون اجزای مختلف feature هامون رو تست و بررسی کنیم که خروجی مورد نظر رو داریم یا نه.

مثلا jest میاد یکسری امکانات مثل matchers ها یا مثلا Async test یا کارای دیگه مثل timer , snapshots و غیره رو در اختیار شما قرار میده که اون تست هارو بتونید بنویسید و شبیه سازی های مورد نظر رو داشته باشید.

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

شروع به نوشتن اولین تست / unit-test

همانطورکه گفتیم اول خبری از کد نیست و باید تست هامون رو بنویسیم. ولی اینجا چون من می خوام اول jest رو توضیح بدم لازم می دونم یکم خود تست نوشتن رو توضیح بدم و امکان داره کدهای تست که می نویسم واقعب نباشن ولی مفهوم و دلیل استفاده از هر قابلیت رو توضیح بدم. یعنی می خوام فعلا بگم هر کدوم از matcher ها چی هستن یا چطور باید ازشون استفاده کنیم , اینها رو که یاد گرفتیم میریم سراغ flow اصلی و رسیدن به کدها از سمت تست.

در قسمت قبل گفتم که یک فولدر به نام __tests__ درست می کنیم و تمام فایل های تست رو اونجا قرار میدیم و مثلا یک فایل با این اسم درست کنید : first.test.js

-- استفاده از Jest Matchers

نصب خود jest رو که در مقاله قبلی گفتیم , حالا نوبت میرسه به matcher ها و انواع اونها. ببینید موقعی که شما می خواید یک تکه کد رو تست کنید باید بررسی کنید که خروجی با چیزی که مد نظر داشتید برابر هست یا نه دیگه ؟ درسته ؟ خوب اینکه برابر بودن رو تست کنید چجوریه ؟ match بودن خروجی متد یا کد با چیزی که مد نظر داشتید باید چطور صورت بگیره ؟ بله اینها با matcher ها انجام میشه. دوتا از مهم ترین هارو اینجا با مثال توضیح میدم و بقیه رو چون واقعا زیاده از سایت مرجع که بعدا لینک میدم بخونید بهتره.

-- معرفی toBe , toEqual و ()test

در این مثال ما یک تست می نویسیم که قراره بررسی کنه آیا مجموع جمع دو عدد توسط یک تابع برابر با عدد مورد نظرمون یعنی 15 هست یا نه ؟ به کد زیر توجه کنید :

test('testing sum', () => {
        expect(sum(10, 5)).toBe(15);
});

خوب ما اول هیچ کدی ننوشتیم و تابع sum رو ایجاد نکردم و طبق flow اول تست رو نوشتیم که قطعا با اجرای دستور npm run test به خطا خواهید خورد که اولا تابع sum وجود نداره و دوم اینکه این تست failed شده و بقیه ماجرا ....

موارد بالا رو توضیح بدم : همانطورکه در کد می بینید از toBe استفاده کردیم که برابر بودن رو بررسی کنیم و از expect برای اینکه تعیین کنیم چه چیزی انتظار میره و از روی معنی انگلیسی اش هم معلومه. البته از ()test هم استفاده کردیم که default خود jest هستش و دو ورودی میگیره. اولی اسم تست یا توضیحاتشه که می نویسیم و بصورت string هستش و روی terminal بعد از هربار اجرا نشون داده میشه و دومی تابع ورودی که بدنه اش میشه محتوای تست.

حالا می خوایم کد رو بنویسیم و دوباره تست کنیم. در نظر داشته باشید بخاطر راحتی و آموزشی بودن من بالای همین تست تابع sum رو می نویسم , ولی درست این هست که جایی دیگه وجود داره که Require یا Import خواهد شد :

function sum(a, b) {
    return a + b;
}
test('testing sum', () => {
    expect({sum(10, 5)}).toBe(15);
});

خوب دوباره با save کردن فایل چون watchAll-- داشتیم نتیجه رو خودش خودکار آپدیت و تست رو مجدد اجرا می کنه. خواهید دید که اینبار خطا ندارید و یک تست از یک passed شده و با رنگ سبز نمایش میده.

حالا بیایم دو تا array یا object رو تست کنیم ببینیم برابر هستن یا نه ؟

var one = ['Ali', 'Reza', 'Mohammad'];
var two = ['Ali', 'Reza', 'Mohammad'];
test('testing sum', () => {
    expect(one).toBe(two);
});

خوب خروجی چی شد ؟ بله خطا میده. چون toBe یک matcher مناسب برای چک کردن دو خروجی یکسان هستش ولی اینجا آرایه ها شاید از نظر مقدار value ها برابر باشند ولی چون در جاوااسکریپت object ها بخاطر رفرنس های متفاوت باهم برابر نیستن و آرایه یه نوع object هست نمی تونه این رو بررسی کنه و باید از toEqual استفاده کنید. یعنی می خواستم بهتون فرق بین toBe و toEqual رو بگم.

یکبار خودتون بجای toBe از toEqual استفاده کنید ببینید چی میشه ؟ باید تست passed بشه ....

نتیجه گیری

تا به اینجا دوباره درباره TDD گفتیم و توضیحات رو بیشتر کردم و در مورد مراحلش هم نوشتم. معلوم شد که testing framework ها چی هستن و اینکه ما داریم در مورد کدومش توضیح میدیم. یک تست نوشتیم و دو یا سه تا از موارد کاربردی مثل toBe - toEqual و test رو توضیح دادیم که تا به اینجای کار دوست دارم خودتون کنجکاو باشید و تست های یکم متنوعی بنویسید و با همین 2-3 مورد که یاد دادم بیشتر سر و کله بزنید و باهاشون آشنا بشید.

نمی خوام خیلی مقالات طولانی و حوصله سر بر باشن , پس تا مقاله بعدی خدانگهدار