برنامه نویسی تست محور (TDD) - قسمت سوم یک مثال عملی

حالا که با مفهوم برنامه نویسی تست محور آشنا شدیم و دیدیم که چرخه این تکنیک به چه صورت کار میکنه، میخوایم باهم یک مثال عملی رو با استفاده از NodeJS پیاده سازی کنیم. در ابتدا پیش نیاز ها رو باهم آماده میکنیم، بعد میریم سراغ ساخت پروژه و در انتها مشغول نوشتن کد برنامه میشیم.

آماده سازی پیش نیاز ها

خوب حالا میخوایم مفاهیم TDD رو توی یک برنامه NodeJS پیاده سازی کنیم. بیاید باهم همون مثال ماشین حساب رو که تو قسمت دوم باهم راجع بهش صحبت کردیم رو پیاده سازی کنیم. ما برای این برنامه از تکنولوژی های زیر استفاده میکنیم:

  • ماژول Mocha: که از اون برای اجرای تست ها استفاده میکنیم.
  • ماژول Chai: که یک کتابخانه مدیریت خطا ها هستش.

برای پیاده سازی این مثال لازم داریم تا موارد زیر رو آماده داشته باشیم:‌

  • فریمورک NodeJS از قبل نصب شده باشه. ( از اینجا میتونید برای نصب اقدام کنید )
  • آشنایی با مفاهیم تست ( آشنایی اولیه، نیاز نیست تا در زمینه تست حرفه ای باشید ) مخصوصا مواردی که در قسمت های اول و دوم راجع بهشون صحبت کردیم.
  • آشنایی پایه ای با NodeJS

اولین مرحله برای شروع نصب Mocha هستش. Mocha یک فریمورک تست هستش که تو پروژه های NodeJS ازش استفاده میشه. نصب Mocha خیلی سادس و شما به راحتی با دستور زیر میتونید اون رو نصب کنید:

npm install -g mocha 

همچنین نیاز داریم کتابخانه Chai رو برای مدیریت خطا ها به پروژه خودمون اضافه کنیم. برای اینکار دستور زیر رو توی ترمینال وارد میکنیم:

npm install chai --save-dev

ساخت پروژه NodeJS

برای این مثال ما از expressJS استفاده میکنیم. میتونید از Express Generator برای ساخت پروژه استفاده کنید. برای اینکار دستور زیر رو توی ترمینال وارد میکنیم:

express tdd_test

حالا باید پیش نیاز ها رو نصب کنیم:

npm install

بعد از ساخت پروژه باید اسکرپت تست خودمون رو به فایل package.json اضافه کنیم.

...
"scripts": {
     "start": "node ./bin/www",
     "test": "mocha test"
},
...

با اینکار هر موقع که دستور npm test رو اجرا کنیم mocha اجرا میشه.

ما توی ساختار برنامه لاجیک برنامه رو توی پوشه controllers قرار میدیم و برای عملیات مورد نظرمون فایل operations.js رو توی این پوشه میسازیم.

کدنویسی

از اونجا که Mocha بطور پیش فرض فایل های تست رو از مسیر test میخونه لازم داریم تا این پوشه رو تو شاخه اصلی پروژه بسازیم. داخل این پوشه فایل اصلی تست ها رو با اسم index.test.js میسازیم. این فایل مرجع همه تست های ما به حساب میاد و تست ها رو داخل اون import میکنیم.

خوب حالا که ساختار برنامه رو آماده کردیم، بیاین مراحل چرخه تست رو که تو قسمت های اول و دوم یادگرفتیم روی این پروژه اعمال کنیم:

۱. نوشتن تست برای امکانات مورد نظر

داخل پوشه test یک پوشه جدید به نام controllers میسازیم. توی این پوشه تمامی تست های مربوط به کنترلرهای خودمون رو مینویسیم. حالا توی این پوشه فایلی به اسم controller.test.js رو میسازیم. اگه یادتون باشه هدف ما نوشتن تستی جهت متد add هستش، برای همین باید تمامی لاجیک مورد نیاز برای این تست رو اینجا پیاده سازی کنیم. اگه از قسمت قبل یادتون باشه لاجیک مورد نظر ما به این صورت هستش:

دریافت دو مقدار عددی از ورودی و بازگشت پاسخ صحیح در خروجی.

خوب حالا کد تست رو بصورت زیر مینویسیم:

var expect = require('chai').expect;
var addOp = require('../../controller/operations').addOp;

describe('Math', ( ) => {
     describe('#add function', ( ) => {
          it ('should returns the result number from the two arguments', ( ) => {
                var result = addOp(1,2); 
                expect(result).to.equal(3);
          });
     });
});

همونطور که توی این کد میبنید ما اول اومدیم متد expect رو از کتابخونه تست خودمون (Chai) اضافه کردیم. بعد از اون امکاناتی رو که قراره بعدا پیاده سازی کنیم رو به برنامه تست اضافه کردیم. در ادامه توی کد تست خودمون اومدیم دو تا عدد ۱ و ۲ رو به متد add دادیم و انتظار داریم که عدد 3 رو که جواب صحیح هستش توی خروجی دریافت کنیم. تا اینجای کار تو این مرحله ما هیچ کدی رو پیاده سازی نکردیم و تنها تست مربوطه رو آماده کردیم.

۲. اجرای تست و مشاهده خطا های دریافتی

همونطور که دیدید تا اینجای کار ما هیچ کدی رو پیاده سازی نکردیم و فقط تست های مربوطه رو نوشتیم. حالا بیاین ببینیم با اجرای تست ها چه نتیجه ای دریافت میکنیم.

برای اینکه تست رو اجرا کنیم ابتدا باید تست خودمون رو به فایل index.test.js اضافه کنیم.

require('./controllers/controller.test');

حالا با اجرای دستور زیر تست رو اجرا میکنیم:

npm test

همونطور که میبینید با پیغام خطای TypeError: addOp is not a function روبرو شدیم. این بدین معناست که متد add هنوز به کنترلرمون اضافه نشده.

۳. پیاده سازی ساختار امکانات مورد نظر:

توی این مرحله ما میخوایم که ساختار امکاناتی رو که میخوایم پیاده سازی کنیم رو آماده کنیم. برای همین به سراغ فایل operations.js که قبلا ساختیم میریم و ساختار متد addOp رو بصورت زیر توی این فایل آماده میکنیم:

exports.addOp = function (var1, var2) {
};

تو این مرحله ما فقط ساختار متد add رو آماده کردیم و به همین دلیل ما میتونیم این متد رو توی فایل تست import کنیم و دو تا ورودی رو بهش پاس بدیم.

۴. اجرای تست و مشاهده نوع خطا

حالا بیاین یک بار دیگه تست رو توی این مرحله اجرا کنیم:

npm test

با اجرای تست میبینید که با خطای زیر روبرو میشیم:

۵. پیاده سازی لاجیک برنامه

توی این مرحله میخوایم تا متدی که قبلا ساختیم رو کامل کنیم و لاجیک برنامه رو بهش اضافه کنیم. با توجه به نیازمندی اعلام شده ما باید دو تا عدد رو از ورودی بگیریم، عمل جمع رو روی این دو عدد انجام بدیم و نتیجه رو توی خروجی برگردونیم:

exports.addOp = function (var1, var2) { 
     const num1 = isNaN(var1) ? 0 : var1;
     const num2 = isNaN(var2) ? 0 : var2;
     
     return num1 + num2;
};

۵. در نهایت پاس شدن تست ها

تو این مرحله تنها کافیه تا تست رو مجددا اجرا کنیم و شاهد پاس شدن تست هایی که نوشتیم باشیم:‌

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

امیدوارم که از این سری آموزشی استفاده لازم رو برده باشید و با تکنیک برنامه نویسی تست محور (TDD) آشنا شده باشید. اگه دوست داشته باشید میتونید وبلاگ من رو کنید و مطالب جدیدی رو که تو زمینه تکنولوژی مینوسم مطالعه کنید.

https://virgool.io/@r.a.majd/test-driven-development-part-1-snpzq4ohai2x
https://virgool.io/@r.a.majd/test-driven-development-part-2-ygwj8tzd6rta