توسعه نرم‌افزار با روش TDD یا Test Driven Development

معمولا توی بیشتر شرکت‌ها وقتی تسکی به یه برنامه‌نویس محول میشه، هیچ مطالعه‌ی درستی روی ورودی و خروجیش انجام نشده. نه تنها خود کارفرما نمی‌دونه چی می‌خواد، که خود برنامه‌نویس هم نمی‌دونه داره چی می‌نویسه و چه انتظاری داره از برنامه‌ای که در حال توسعش هست!

این مشکل وقتی خیلی به چشم می‌خوره که تیم بزرگ بشه و مسئول توسعه‌ی هر بخش یک نفر باشه. تست نوشتن و داکیومنت نوشتن هم که برای برنامه‌نویس‌ها مثل شکنجست. کد رو می‌نویسن و می‌گن کار می‌کنه دیگه. این می‌شه که فردایی پس‌فردایی که قراره یه فیچر جدید به اپلیکیشن اضافه بشه یهو می‌بینی همه چی از بیخ و بن از کار افتاد! حالا تو بدو ارور استک بدو!

کد نویسی به روش TDD یا Test Driven Development

شما فرض می‌کنین که وقتی به یه‌نفر می‌گین «دوستت دارم» جوابش «مرسی» باشه! پس خودتون برای این ضایع شدن آماده می‌کنین و شرایط رو برای این شکست آماده می‌کنین و می‌رین و پیشنهاد می‌دین!

یه فرض محال دیگه که وقتی به یه‌نفر می‌گین «دوستت دارم» جوابش «منم دوستت دارم» باشه! پس شما می‌دونید که قراره به احتمال هرچند کم خوش‌بخت بشین، پس شروع می‌کنید به آماده سازی شرایط?

توی دو مثال بالا شما کامل می‌دونید ورودی‌تون چیه «دوستت دارم» و خروجی قراره تو هرکدوم از این شرایط چی باشه: ۱-مرسی ۲-منم دوستت دارم و ... . اما شخص مقابلی وجود داره؟ نه لزوما! شما فقط می‌دونید در جواب این سوال این دو خروجی صادر می‌شه.

رو به دیوار می‌ایستین و می‌گین «دوستت دارم»!

دیوار:

Response:
    status: 404
    message: Route not found exception

خب چی شد؟؟ شما از ورودی و خروجی‌تون مطمئن بودین ولی آیا جای درستی ازش استفاده کردین؟ نه!

حالا که فهمیدیم نمیشه به دیوار عشق ورزید می‌ریم مدت‌ها و سالیان می‌گردیم و می‌چرخیم و یک نفر رو که فکر می‌کنیم گزینه مناسبیه پیدا می‌کنیم و رو بهش می‌ایستیم و بهش می‌گیم: «دوستت دارم»

شخص مناسب:

Response:
    status: 403
    message: You are not authorized to do this

باز مشکل کجاست؟ مشکل این‌جاست که شخص رو پیدا کردین ولی آیا مقدمات رو آماده کرده بودین؟ اون طفلک روحشم از قضیه خبر داشت آیا؟ مسلما نه!

زمان می‌ذارین بهش توجه می‌کنین و بعد از یه مدت که طرف مقابل دوزاریش افتاد. مجدد رو بهش می‌گین: «دوستت دارم»

یکی از پاسخ‌های احتمالی شخصِ مناسبِ آماده شده:

Response:
    status: 200
    message: منم دوستت دارم

پاسخ احتمالی دوم:

Response:
    status: 204
    message: مرسی

پاسخ احتمالی سوم:

Response:
    status: 301
    message: منم دوستت دارم داداشی/خواهر گلم

و یه‌سری پاسخ دیگه!

ما این‌جا چه کردیم؟ یه پروسه‌ای (تست) توی مغزمون تشکیل دادیم که در ازای این ورودی چه خروجی‌هایی ممکنه تحویل بگیریم. و یک بار پروسه‌رو صدا کردیم (تست اولیه) ولی چون کدی وجود نداشت، اتفاقی نیفتاد. پس به‌صورت ابتدایی تا اونجا که فکر می‌کردیم درسته پروسه‌رو آماده کردیم (دولوپ) و باز اون چیزی که تو ذهنمون بود را اجرا کردیم (تست). به ارور خوردیم چون فکر یه‌جایی - آماده بودن کامل موقعیت - رو نکرده بودیم. پس با انجام یک‌سری تغییرات (دیباگ) دوباره تست رو انجام دادیم (تست). این پروسه رو انقدر انجام می‌دیم تا تمام باگ‌ها گرفته بشه و در ازای ورودی‌های ما خروجی‌های مورد انتظارمون برآورده بشن.

حالا چرا باید اول تست بنویسیم، بعد کد؟

یکی از مهم‌ترین مزایای این روش به‌نظرم اینه که شما با نوشتن تست اولیه، تکلیفتون رو با خودتون مشخص می‌کنید و اگر چیزی رو ندونید یا سوالی اون گوشه‌های ذهنتون قایم شده باشه پیدا می‌شه و قبل شروع به‌کار حلشون می‌کنید و از ری‌فکتور کردن‌های بیهوده اجتناب می‌کنین.

یکی دیگه از مزایای این روش باز هم به‌نظر من اینه که شما وقتی اول کد رو بنویسین و بعد به‌زور بیاین تستش رو بنویسین، در حقیقت دارین خودتونو گول می‌زنین. انگاری اول درو بسازین، قفلشم بسازین. بعد سعی کنین با خمیر و آدامس (عین این فیلما) کلیدی که اون در رو باز می‌کنه رو بسازین! قشنگ‌تر نیست اگر اولش بدونین این کلید این قفل رو باز می‌کنه و بعد قفل رو روی یه در سوار کنین؟

یکی دیگه از مزیت‌هاشم به‌نظر من اینه که وقتی اول تست رو بنویسین، آخر پروژه درگیر فرآیند خسته کننده تست نوشتن نمی‌شین و احتمال زیاد بخش زیادی از تست‌ها رو نمی‌پیچونید!

و در آخر هم وقتی همه‌ی کدتون با تست نوشته شده باشه، با هر ریلیز، راحت با انجام یه تست یک‌پارچگی از سلامت نرم‌افزارتون مطمئن می‌شین!

اولین بار که با این روش آشنا شدم، مغزم خیلی مقاومت کرد ولی الان که چند وقتیه این‌جوری کد می‌زنم به‌نظرم اومد که چرا از اول این‌کارو نمی‌کردم؟!