۱۳۹۹/۰۶/۰۹

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , , ,


 

برای اعمال تغییرات بر روی فایروال با استفاده از firewall-cmd در CentOS میتونیم به صورت زیر عمل کنیم:

۱. وضعیت فعلی قوانین فایروال

$ sudo firewall-cmd --list-all

۲. اضافه کردن یک سرویس

$ sudo firewall-cmd --add-service=http

۳. اضافه کردن یک پورت

$ sudo firewall-cmd --add-port=1234/tcp
$ sudo firewall-cmd --add-port=1234/udp

۴. برای ذخیره تغییرات اعمال شده از سوییچ --premanent استفاده میکنیم:

$ sudo firewall-cmd --premanent --add-port=1234/tcp

 

۱۳۹۸/۱۲/۰۱

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , , ,

توی این سری میخوام نکاتی رو در مورد برنامه نویسی به زبان C++ بطور مختصر و با زبان ساده توضیح بدم.
تو اولین پست از این سری میخوام راجع به rvalue ها در c++ بنویسم. یکی از مواردی که برای خیلی از برنامه‌نویس‌ها ممکنه مقداری نامفهوم باشه.

مفهوم rvalue ها در c++ به مقادیر موقتی گفته میشه که به طور معمول در سمت راست یک expression قرار میگیرن. میشه اونها رو به یک متغیر اختصاص داد، اما نمیشه مقداری رو به اونها تخصیص داد. مقادیر عددی یا فراخوانی توابع مثال هایی از استفاده از rvalue ها در c++ هستش. تو مثال زیر `1` و `foo()` مثال هایی از rvalue هاست که برای مقداردهی اولیه متغیرهای `a` و `b` استفاده شده. به `a` و `b` در این مثال `lvalue` گفته میشه.


int a = 1;
int b = foo();


همچنین مثال های زیر نمونه هایی از مقدادهی نادرست بوده که امکان موقع کامپایل با خطا روبرو میشه:

1 = c; // error
foo() = d; // error

حالا چطور تعیین میکنیم که یک متغیر موقتی هستش؟‌ بطور کلی مقداری رو موقتی میدونیم که متغیری به اون مرتبط نشده باشه.

Int bar = 1; // bar is a name, so it is an lvalue.
2; // 2 is an integer literal, it has no name (no identifier). It's an rvalue.

مورد دیگه ای که میتونیم برای تشخیص rvalue ها استفاده کنیم اپراتور آدرس `&` هستش. توی c++ نمیتونیم آدرس rvalue ها در حافظه رو بگیریم.

int a = 1;
&a; // Works, address of a stack-allocated variable.
&1; // Error, 1 is an integer literal.
&foo(); // Error, cannot take address of the temporary result of a function call.

یکی از جاهایی که rvalue ها به ما کمک میکنن move semantics هستش که تو پست های بعدی راجع بهش صحبت میکنیم.

۱۳۹۸/۱۰/۲۹

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , ,

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

تعریف ماکرو

طبق تعریف ارائه شده در مستندات GCC، ماکرو در حقیقت تکه کدی هستش که براش نامی رو در نظر میگیریم. هرجا از برنامه که از این نام استفاده کرده باشیم کامپایلر قبل از شروع به کامپایل اون رو با تکه کد مربوطه جایگزین میکنه.

ما بطور کلی دو نوع استفاده از ماکرو داریم:
  • نوع اول object-like macros: که برای مشخص کردن مقادیر استفاده میکنیم.
  • نوع دوم function-like macros: ماکرو هایی که برای جایگزاری یه قطعه کد در برنامه استفاده میشن.

موارد معمول استفاده از ماکروها

حالا که یه تعریف کلی از ماکرو ارائه دادیم بریم سراغ استفاده های مختلف اون در برنامه ها:

۱. تعریف مقادیر ثابت پیش‌فرض

یکی از استفاده هایی که از ماکرو میشه اینه که مقادیر ثابت رو در بخشی از برنامه تعریف کنیم و از اون در جاهای مختلف برنامه استفاده کنیم:

#define PORT 8080
#define LOG_PATH "/path/foo/bar"
#define DEBUG_MODE 1

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

همچنین میتونیم با استفاده از pre-processor flags برنامه رو با توجه به محیط مقصد کامپایل کنیم:



کامپایل بصورت پیش‌فرض:

$ gcc macro.c
$ ./a.out
compiled with: default flag 

تغییر MYFLAG در هنگام کامپایل:

$ gcc -DMYFLAG='"modified flag"' macro.c
$ ./a.out
compiled with: modified flag

۲. تعریف یک عملیات خاص توسط ماکرو

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

#define MAX(a,b) (a>b ? a : b)
#define EXISTS(array, vector)  (vector.find(value) != vector.end())

از اونجایی که کد مرتبط با ماکرو قبل از کامپایل با ماکرو جایگزین میشه سرعت برنامه در این حالت بالاتر میره، البته این مورد در مقایسه با توابع inline فرق خاصی نداره و تنها تفاوتش در اینه که توابع inline توسط کامپایلر مدیریت میشن ولی ماکرو ها توسط pre-processor مدیریت میشن.

امکانات قابل استفاده در تعریف ماکرو ها

۱. تبدیل متغیر ماکرو به متن

در حالت عادی متغیرها / عبارت هایی رو که به ماکرو پاس میدیم اول محاسبه (evaluate) میشن و بعد به بدنه ماکرو ارسال میشن، ولی اگه بخوایم ورودی که به ماکرو ارسال شده رو داشته باشیم میتونیم با اضافه کردن کاراکتر `#` قبل از ورودی مورد نظر اون رو بصورت یک رشته داشته باشیم:



خروجی برنامه:

$ gcc macro2.c
$ ./a.out
Warning: x == 1

۲. اتصال پارامترهای ماکرو

بعضی مواقع لازم داریم تا مقداری رو به پارامترهای یک ماکرو اضافه کنیم در این موارد میتونیم این مقاریر رو با استفاده از `##` به هم متصل کنیم. برای بهتر فهمیدن مورد استفاده این امکان ماکرو اون رو با یک مثال توضیح میدیم:‌



خروجی برنامه:

$ gcc macro3.c
$ ./a.out
quit command executed.
help command executed.

توی این مثال با استفاده از ماکرو `MKCMD` آرایه رو با name و function مربوطه بصورت خودکار initiate کردیم.

۳. ماکرو با آرگومان های متغیر

برخی مواقع لازمه که ماکرو ما تعداد متغیری ماکرو داشته باشه. برای این موضوع مثل تعریف توابع با پارامترهای متغیر نام ماکرو رو با `...` مشخص میکنیم و هنگام استفاده `__VA_ARGS__` رو بکار میبریم:

#define eprintf(…) fprintf (stderr, __VA_ARGS__)
...
eprintf ("%s:%d: ", input_file, lineno);  
// above line will be replaced with following:
//           fprintf (stderr, "%s:%d: ", input_file, lineno)

بعضی مواقع وقتی ماکرو ما خیلی پیچیده میشه میتونیم قبل از `...` یک نام رو برای بخش متغیر پارامترها تعیین کنیم و در ادامه از اون نام استفاده کنیم. فقط باید توجه کنیم که نمیتونیم این روش رو با همراه با __VA_ARGS__ استفاده کنیم.

#define eprintf(args...) fprintf(stderr, args)

ما همچنین میتونیم از پارامترهای با نام در کنار پارامترهای متغیر استفاده کنیم:

#define eprintf(format, …) fprintf (stderr, format, __VA_ARGS__)

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , , , , ,


یکی از ابزاری که در نبود IDE مخصوصا در محیط ریموت میتونه کمکمون کنه تا دلیل کرش کردن برنامه رو کشف کنیم استفاده مستقیم از خود GDB هستش.

برای مثال برنامه زیر رو که موقع اجرا خطا میده میخوایم با GDB دیباگ کنیم:

وقتی به صورت عادی برنامه رو اجرا کنیم با خطای زیر روبرو میشیم:‌

$ ./hello
Floating point exception

اجرای برنامه بوسیله GDB

برای اینکه برنامه رو با gdb اجرا کنیم کافیه تا اون رو به عنوان ورودی به GDB بفرستیم و بعد با دستور `run` برنامه رو اجرا کنیم:

$ gdb ./hello
(gdb) run




و موقع بروز خطا با استفاده از back trace به بررسی مشکل بپردازیم:

(gdb) bt


همونطور که میبینید GDB اطلاعاتی راجع متدی که خطا در اون پیش اومده در اختیارمون قرار میده.



ذخیره لاگ در فایل

برای این منظور باید قبل از اجرای برنامه با دستور run تنظیمات لاگ مربوط به GDB رو بصورت زیر انجام بدیم:


(gdb) set logging on
(gdb) set logging file /path/to/log/file


همچنین برای مشاهده تنظیمات فعلی لاگ GDB از دستور زیر میتونیم استفاده کنیم:

(gdb) show logging


نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , ,

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


جدیدا بخاطر سیاست شرکت جدید مجبور شدم از eclipse به Jetbrains CLion سوییچ کنم و این یعنی استفاده از CMAKE بجای build system داخلی eclipse. یکی از مواردی که تو روز اول کار با `CLio بهش برخوردم لینک کردن library های خارجی به برنامه خودم بود. برای اینکار از pkg-config استفاده کردم و بعد از نصب library مورد نظر، موارد زیر رو باید به فایل CMakeList.txt خودمون اضافه کنیم.

find_package(PkgConfig REQUIRED)
pkg_check_modules(TITLE lib-name REQUIRED)

include_directories(${TITLE_INCLUDE_DIRS})
link_directories(${TITLE_LIBRARY_DIRS})
link_libraries(${TITLE_LIBRARIES})
نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , , ,


حالا که با مفهوم برنامه نویسی تست محور آشنا شدیم و دیدیم که چرخه این تکنیک به چه صورت کار میکنه، میخوایم باهم یک مثال عملی رو با استفاده از 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) آشنا شده باشید. اگه دوست داشته باشید میتونید وبلاگ من رو کنید و مطالب جدیدی رو که تو زمینه تکنولوژی مینوسم مطالعه کنید.


نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , , ,


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

ابتدا بیایم با مفهومی که باید تست بشه آشنا بشیم...

 

فرض کنید که مشتری از ما درخواست داشته تا یه نرم‌افزار ماشین حساب براش تولید کنیم که فقط کار جمع رو انجام بده، نه بیشتر و نه کمتر. همونطور که میدونید خیلی راه برای توسعه همچین برنامه ای وجود داره. یه سری میان ساختار کلی برنامه رو آماده میکنن، یه سری دیگه اول به طراحی رابط کاربری مشغول میشن، و خیلی روش های دیگه که ممکنه به ذهنتون برسه. ما اینجا قصد داریم تا بخش لاجیک این برنامه رو با تکنیک TDD پیاده سازی کنیم. درسته که کار پیچیده ای نیست، اما باعث میشه تا با مفاهیم TDD بهتر آشنا بشیم و قدرت اون رو بهتر درک کنیم.
خوب حالا بیایم مراحل TDD رو که توی پست قبل باهاشون آشنا شدیم توی توسعه لاجیک برنامه خودمون بکار ببریم:

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

همونطور که گفتیم، اولین مرحله نوشتن تست هستش. نیازمندی ماشین حساب ما رو که به یاد دارید «عمل جمع». برای همین اسم متد تست خودمون رو «Add» میزاریم ( توی این مرحله لاجیک کامل برای تست متد Add رو پیاده سازی کنیم ). وقتی که برای عمل جمع متد تست مینویسیم، انتظار داریم که متد ما دو تا ورودی عددی رو به عنوان ورودی بگیره و مجموع این دو عدد رو توی خروجی برگردونه.

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

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

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

توی این مرحله ما ساختار برنامه خودمون رو آماده میکنیم. ( هنوز کاری با لاجیک برنامه نداریم. ) متد Add رو با دو ورودی عددی و همچنین خروجی عددی تعریف میکنیم.

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

دوباره تست رو اجرا می‌کنیم. این دفعه خطایی که دریافت میکنیم مربوط به عدم تطبیق خروجی متد و مقدار مورد انتظار ما خواهد بود.

۵. پیاده سازی لاجیک

توی این مرحله لاجیک مورد نیاز متد Add رو پیاده سازی میکنیم. این متد دو تا ورودی عددی رو گرفته و مجموع اونها رو توی خروجی بر میگردونه.

۶. مشاهده پاس شدن همه تست ها

بالاخره به بهترین بخش کار رسیدیم. جایی که تست های ما پاس شده و خطایی رو توی کنسول مشاهده نمیکنیم. حالا با اطمینان میتونیم برنامه خودمون رو به مشتری تحویل بدیم و خیالمون راحت باشه که مطمئنا برنامه به درستی کار میکنه.
به یاد داشته باشید که درصورت اعمال تغییرات نیاز داریم تا تمامی مراحل بالا رو دوباره روی برنامه اعمال کنیم.
در قسمت اول راجع به مفاهیم برنامه نویسی تست محور صحبت کردیم و توی این قسمت یک مثال ساده رو باهم بررسی کردیم، اگه تا اینجای کار از این سری مطالب خوشتون اومد میتونید تو قسمت سوم همراه با ما باشید تا این مثال رو بصورت عملی باهم پیاده سازی کنیم.
نوشته شده توسط Reza Alizadeh Majd
دسته بندي: , ,

اینکه بخوایم برنامه نویس خوبی باشیم کار ساده ای نیست و باید همواره دانش خودمون رو بروز کنیم و در رابطه با تکنولوژی های جدید مطالعه داشته باشیم، وگرنه از جامعه عقب میمونیم و کم کم از دور رقابت خارج میشیم. این بروز بودن فقط محدود به فریمورک ها و زبان های برنامه نویسی و بانک های اطلاعاتی نمیشه، ما باید درباره تکنیک های جدید برنامه نویسی هم مالعه داشته باشیم تا بتونیم کیفیت کار خودمون رو هم بالا ببریم. یکی از این تکنیک های جدید که کمک میکنه تا سرعت بیشتری در توسعه داشته باشیم و هزینه توسعه پایین بیاد، برنامه نویسی تست محور یا Test Driven Development هستش که در اختصار بهش TDD میگن.

تعریف برنامه نویسی تست محور

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

اهمیت تست ...

برای اینکه اهمیت برنامه نویسی تست محور برامون روشن بشه، اول باید اهمیت نوشتن تست رو درک کنیم. ما برنامه نویس ها معمولا زمان کافی برای نوشتن تست برای کد خودمون رو نداریم، بعضی از ما موقع توسعه فکر میکنیم که کدمون مشکلی نداره، خیلی وقت ها هم ممکنه محدودیت های زمانی که برای تحویل نرم‌افزار به کارفرما / مشتری داریم مانع از نوشتن تست برای کد ما بشه. اگه ما تست برای کد خودمون ننویسیم، باگها تو محیط مشتری خودشون رو نشون میدن و این اصلا موضوع جالبی نیست. ما باید سعی کنیم که به نوشتن تست ها به عنوان بخشی از توسعه نرم افزار عادت کنیم. نه بخاطر اینکه برخی نیازمندی ها این رو از ما میخوان بلکه بخاطر اینکه کد با کیفیت تری داشته باشیم نیاز هستش که تست های کاملی بنویسیم. این کار مطمئناً بتدا زمان بیشتری رو ازمون می‌گیره اما در نهایت باعث میشه تا باگ های کمتری داشته باشیم و کمتر مجبور به دوباره کاری باشیم.

شش قانون در توسعه تست محور

میتونیم توسعه تست محور رو توی ۶ مرحله ساده زیر خلاصه کنیم:
  1. نوشتن تست برای امکانات مورد نظر
  2. اجرا کردن تست ها و مشاهده خطاهایی که دریافت میکنیم
  3. پیاده سازی ساختار فیچر مورد نظر
  4. اجرای مجدد تست ها و بررسی خطا های دریافتی
  5. پیاده سازی لاجیک
  6. بررسی پاس شدن تست های نوشته شده
همونطور که میبینید تو این ۶ مرحله به هیچ وجه قبل از اینکه تست ها رو بنویسیم درگیر نوشتن خود متد یا امکانات مورد نظرمون نشدیم. اگه این روش رو پیش بگیزیم میتونیم مطمئن باشیم بخش عمده ای از کدمون قبل از ورود به محیط پروداکشن تست شده و در ادامه با خطاهای کمتری مواجه خواهیم شد.
حالا که با مفاهیم برنامه نویسی تست محور آشنا شدیم، توی قسمت بعد میخوایم تا با استفاده از یک مثال ساده به طور عملی با این مفاهیم برخورد داشته باشیم و بهتر این تکنیک رو درک کنیم. پس اگه این مطلب براتون جذاب بود پیشنهاد میکنم قسمت دوم رو هم مطالعه کنید.

۱۳۹۵/۱۰/۳۰

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: ,
پلاسکو در آتش سوخت و با خودش آتش نشان هایی رو برد که
شجاعتشون باعث شده ما امروز احساس امنیت و آرامش بکنیم...

۱۳۹۵/۰۸/۲۱

نوشته شده توسط Reza Alizadeh Majd
دسته بندي: ,
RIP Leonard Cohen (1934 - 2016)