টেস্ট ড্রাইভেন ডেভলপমেন্ট
সফ্টওয়্যার ডেভলপমেন্ট বলতে কম বেশি আমরা সবাই সেটা বুঝি । সেই সফ্টওয়্যারের টেস্টিং বলতে যেটা বলা হয় সেটাও কম বেশি বুঝি । আজ আমরা যেটির সম্পর্কে জানবো সেটি হল টেস্ট ড্রাইভেন ডেভলপমেন্ট বা সংক্ষেপে TDD।
টেস্ট ড্রাইভেন ডেভলপমেন্ট বলতে সহজ কথায় বোঝায় কোন একটি কোড সেগমেন্ট লেখার সাথে সাথে সেটি টেস্ট করা যে এই কোড সেগমেন্টটি তার পূর্ন রিকোয়ারমেন্ট সম্পূর্ন করতে পারছে কি না । অর্থাৎ , আপনি কোন একটি কোড বা লজিক লিখলেন, সেই সঙ্গে সঙ্গে সেটি যত রকম ইনপুট ফেস করতে পারে সব রকম ইনপুটের জন্যই টেস্ট করলেন যে সেটি কাঙ্খিত রেজাল্ট বা আউটপুট দিতে পারছে কি না । যদি কোন এক বা একাধিক ইনপুটের জন্য সেটি ফেইল করে তবে সেটিকে আবার ডিবাগ করা এবং যতক্ষন পর্যন্ত না সেটি সম্পূর্ন বাগমুক্ত হচ্ছে ততক্ষন টেস্ট করে যাওয়া এবং কোড রিফ্যাক্টর করা । এই পদ্ধতিটি প্রথম ২০০৩ সালে Kent Beck সাহেব পরিচিত করান । টেস্ট ড্রাইভেন ডেভলপমেন্ট সম্পর্কে ভালো সঙ্গা পেতে উইকিপিডিয়ার এই লিংকটিতে ঘুরে আসতে পারেন ।
প্রশ্ন আসতেই পারে কেন টেস্ট ড্রাইভেন ডেভলপমেন্ট ? ওকে , মনে করুন আপনাকে একটা টেক্সট ফাইল দিয়ে বলা হল এই ফাইলের মাঝে সবচেয়ে বেশি ফ্রিকোয়েন্সির ১০ টি শব্দ নির্বাচন করে দিতে হবে । ব্যাস , আপনি ঝাপিয়ে পড়লেন কোড করতে । পুরা লজিক মাথার ভেরত ছক একে ফেল্লেন , বা খাতা কলম নিয়ে বসলেন ফ্লোচার্ট আকলেন বা অ্যালগোরিদমের সুডো কোড লিখে বসে গেলেন কোড করতে । কাজ করতে করতে শেষের দিকে যেয়ে মাথা গরম হয়ে গেল , এইরে উপরে কি যেন একটা চিন্তা করে এই অ্যাট্রিবিউটটা নিয়েছিলাম ? বা সব ঠিক ঠাক মত শেষ করলেন । যখন কোড রান করলেন দেখা গেল এক গাদা এক্সেপশন দিয়ে বসে আছে । আপনার তো মাথায় হাত । চুল ছিড়তে মত চাচ্ছে । শেষে দেখা গেল আপনি যে ফাইলটি থেকে ডাটা রিড করতে চাচ্ছেন সেই ফাইলটিই ওই ডিরেক্টরিতে ( ফোল্ডার ) এক্সিস্ট করেনা বা সেই ফাইলটির রিড পার্মিশনই নাই । সেটা ঘষে মেজে ঠিক করলেন , অবশ্য তার জন্য অনক কাঠখড় পোড়াতে হল কারন পুরা কোডের স্ট্রাকচারই হয়ত পরিবর্তন করতে হল । যাইহোক , তারপর দেখা গেল কাজ ঠিকই করছে তবে এই শব্দ দুইবার দেখাচ্ছে । অনেকটা এমন যে "good" শব্দটা সবচেয়ে বেশিবার এসেছিল আপনার প্রদত্ত ফাইলে এবং সেটাই প্রথমে দেখানোর কথা ছিল তবে আপনার কোড দেখাচ্ছে যে "Good" এর অবস্থান ৬ তম এবং "good" এর অবস্থান ৯ । বিষয়টা একটু ঝামেলার হয়ে গেল । আমার আপনি সেটা ঠিক করতে বসলেন । এবং যথারীতি নাজেহাল অবস্থা ।
ওকে অনেক হয়েছে । আমরা প্রোগ্রামার মানুষজন এমনিতে অনেক অলস আর মাথা গরম টাইপের । এত ঝামেলার মাঝে যেন পড়া না লাগে সেজন্য আমরা শর্টকাট খুজি । তেমন একটা শর্টকাট হল টেস্ট ড্রাইভেন ডেভলপমেন্ট । বুঝতে সমস্যা হলেও ভয় পাওয়ার কোন কারন নেই । উপরের প্রবলেমটা একটু সহজ ভাবে চিন্তা করি চলুন । কয়েকটা ধাপে আমরা কাজটা করিঃ
ধাপ ১ঃ আমাদের বলা হয়েছে একটা টেক্সট ফাইল পড়ে তার মধ্য থেকে সবচেয়ে বেশি ফ্রিকোয়েন্সির নির্দিষ্ট কিছু শব্দ বাছাই করতে । এসবকিছু করতে গেলে প্রথমেইতো আমাদের টেক্সট ফাইলটি পরথে হবে তাইনা ? ওকে আমরা যে মেথড ( ফাংশন ) টি লিখছি সেটাতে কেবল টেক্সট ফাইলটি রিড করার কোড লিখলাম । এবার আমরা এই ছোট্ট কোডটুকু নানা ভাবে টেস্ট করলাম । দেখলাম এটি সব রকম সিচুয়েশন মিট করতে পারে কি না । ফাইলটি থাকলে রিড করতে পারছে কি না বা না থাকলে কি করা উচিৎ । ফাইলে কোন কনটেন্ট থাকলে কি করা উচিৎ বা না থাকলে কি করা উচিৎ এমন । এটুকু করলে অন্তত আমরা নিশ্চিত যে ফাইল পড়া নিয়ে আর কোন ঝামেলা থাকলো না । এবার আগাই সামনের দিকে ।
ধাপ ২ঃ যেহেতু আমাদের ফাইল রিড করা নিয়ে কোন চিন্তা আর নাই তাই আমরা নিশ্চিন্তে এবার সেখান থেকে কনটেন্ট পড়তে পারি । এবার আমরা একটা একটা করে শব্দ নিয়ে খেলা শুরু করে দিতে পারি । এমন একটা ডাটা স্ট্রাকচার নিয়ে কাজ করতে পারি যেখানে ২ টা ভাগ থাকবে । সি++ এর পেয়ার বা জাভার ম্যাপ বা সি এর স্ট্রাকচার বা নিজ থেকেও কাষ্টম ডাটা স্ট্রাকচার ডিজাইন করে নিতে পারেন । উদাহরন হিসাবে "Map<String, Integer> wordMap" এমনটা ধরে নিতে পারেন । এবার টেক্সট ফাইল থেকে একটা একটা শব্দ পড়লেন আর টেস্ট করলেন সেটা এই ম্যাপে আছে কি না । যদি না থাকে তবে কি হিসাবে ওই শব্দটি এবং ভ্যালু হিসাবে ১ ইনসার্ট করুন । যদি থাকে তবে সেই কি এর ভ্যালুর মান এক বাড়িয়ে দিন । এভাবে আমরা ওই ফাইলে যত শব্দ আছে তাদের ফ্রিকোয়েন্সি পেয়ে গেলাম । এবার টেস্ট করুন , আপনার কোডটি কি কাজ করছে ? হ্যা কাজ ঠিকই করছে তবে "Good" আর "good" এর মাঝে পার্থক্য করে ফেলেছে । কি আর করা সামনে আগাই ।
ধাপ ৩ঃ যেহেতু আগের ২ টা ধাপই সফলভাবে কাজ করছে তাই ওদিকে মাথা না ঘামালেও চলবে । এবার আমরা "Good" আর "good" এর মাঝে ব্যাবধানটা কমাতে হবে । একটা কাজ করলে কেমন হয় ? যদি আমরা যেকোন শব্দকেই আপার কেস বা লোয়ার কেসে কনভার্ট করে ফেলি ? মানে করলাম আমরা সবই লোয়ার কেসে কনভার্ট করবো , তাহলে "Good" = "good" এবং "good" = "good" হয়ে গেল । থাকলো আর কোন পার্থক্য ? না থাকারই কথা । এই ছোট্ট কাজটি আমরা করবো নতুন একটা ওয়ার্ড পড়ে সেটাকে ম্যাপে ইনসার্ট করার সময় এবং চেকিং এর সময় । এবার আমরা টেস্ট করলে দেখতে পাবো, নাহ এবার আর "Good" আর "good" এ গোলমাল হচ্ছে না । ওকে সামনে আগাই ।
ধাপ ৪ঃ কাজতো প্রায় শেষ । এবার আমরা ম্যাপটিকে ভ্যালুর রেসপেক্টে সর্ট করে ফেলতে পারি । সেটা কিভাবে করা হয় সেটা যদি না জেনে থাকেন তবে গুগলে একটু ঘাটাঘাটি করতে পারেন । এই লিংকে খুব সুন্দরভাবে বোঝানো হয়েছে কিভাবে একটি ম্যাপ টাইপ কালেকশন সর্ট করা যায় । অথবা কাষ্টম ডাটা টাইপের জন্য Comparator বা Comparable ইন্টারফেস নিসেও একটু পড়াশোনা করতে পারেন । ব্যাস হয়ে গেল সর্টিং । মনে করলাম ডিসেন্ডিং অর্ডারে সর্ট করেছেন । তাহলে প্রথম দিকের ১০ টি ( বা যতগুলা দেখাতে বলা হয়েছে ) দেখিয়ে দিন । টেস্ট করুন । আরেব্বাহ কাজ করছে তো ! কিন্তু সমস্যা হল ভিন্ন ভিন্ন শব্দ সংখ্যা যদি হয় ৭ টি আর আপনাকে যদি দেখাতে বলা হয় ১০ টি তাহলে তো একটু এক্সেপশন দিচ্ছেই । তাইনা ? ওকে সামনে আগাই ।
ধাপ ৫ঃ যেহেতু সব কাজই শেষ তাই বাড়তি করার মত যেটি থাকতে পারে সেটি হল যদি লিস্টের সাইজ প্রদত্ত নাম্বারের চেয়ে বড় হয় তাহলে কোন সমস্যা নাই ওই নাম্বার সংখ্যক ইটারেশন দিয়েই শব্দগুলা পিক করতে পারবেন । যদি ছোট হয় তাহলে লিস্টের সাইজ পর্যন্ত যান বা বলে দিন কাঙ্খিত নাম্বারের সমান পর্যান্ত শব্দ ওই টেক্সট ফাইলেই নেই । অথবা আপনার কাজের উপর ভিত্তি করে সিদ্ধান্ত নিন । ব্যাস কাজ শেষ !
উপরের ধাপগুলা অনুসরন করে আমরা দেখলাম খুব সহজে এবং বাগফ্রী একটি কোড কিভাবে লেখা যায় । এখানে পুরা কোডটি একবারে লিখে শেষে টেস্ট করতে গিয়ে মাথায় চুড় ছেড়ার কোন প্রয়োজন হয়নি । বরং খুব ছোট্ট ছোট্ট কাজকে বার বার টেস্ট করার মাধ্যমে আমরা আমাদের কাঙ্খিত ফলাফল পেয়ে গিয়েছি । সংক্ষেপে (ব্যাখ্যা অনেক বড় :P ) এটিই হল টেস্ট ড্রাইভেন ডেভলপমেন্ট । যেখানে প্রতিটি ছোট ছোট কাজকে সব রকম ভাবে টেস্ট করে দেখা হয় যে এই অংশটুকু তার চাওয়া পূরন করতে পারছে কি না । যতক্ষন না ওই অংশটুকু সম্পুর্ন শুদ্ধ না হচ্ছে ততক্ষন তার পরবর্তী অংশে হাত দেওয়া হচ্ছে না ।
আজ এই পর্যন্ত । আগামিতে টেস্ট ড্রাইভেন ডেভলপমেন্টের বিভিন্ত প্রসেস এবং বিভিন্ন টুলস নিয়ে আলোচনা করা হবে । আগামি পর্বের লিংক ।
সবাইকে ধন্যবাদ ।
প্রশ্ন আসতেই পারে কেন টেস্ট ড্রাইভেন ডেভলপমেন্ট ? ওকে , মনে করুন আপনাকে একটা টেক্সট ফাইল দিয়ে বলা হল এই ফাইলের মাঝে সবচেয়ে বেশি ফ্রিকোয়েন্সির ১০ টি শব্দ নির্বাচন করে দিতে হবে । ব্যাস , আপনি ঝাপিয়ে পড়লেন কোড করতে । পুরা লজিক মাথার ভেরত ছক একে ফেল্লেন , বা খাতা কলম নিয়ে বসলেন ফ্লোচার্ট আকলেন বা অ্যালগোরিদমের সুডো কোড লিখে বসে গেলেন কোড করতে । কাজ করতে করতে শেষের দিকে যেয়ে মাথা গরম হয়ে গেল , এইরে উপরে কি যেন একটা চিন্তা করে এই অ্যাট্রিবিউটটা নিয়েছিলাম ? বা সব ঠিক ঠাক মত শেষ করলেন । যখন কোড রান করলেন দেখা গেল এক গাদা এক্সেপশন দিয়ে বসে আছে । আপনার তো মাথায় হাত । চুল ছিড়তে মত চাচ্ছে । শেষে দেখা গেল আপনি যে ফাইলটি থেকে ডাটা রিড করতে চাচ্ছেন সেই ফাইলটিই ওই ডিরেক্টরিতে ( ফোল্ডার ) এক্সিস্ট করেনা বা সেই ফাইলটির রিড পার্মিশনই নাই । সেটা ঘষে মেজে ঠিক করলেন , অবশ্য তার জন্য অনক কাঠখড় পোড়াতে হল কারন পুরা কোডের স্ট্রাকচারই হয়ত পরিবর্তন করতে হল । যাইহোক , তারপর দেখা গেল কাজ ঠিকই করছে তবে এই শব্দ দুইবার দেখাচ্ছে । অনেকটা এমন যে "good" শব্দটা সবচেয়ে বেশিবার এসেছিল আপনার প্রদত্ত ফাইলে এবং সেটাই প্রথমে দেখানোর কথা ছিল তবে আপনার কোড দেখাচ্ছে যে "Good" এর অবস্থান ৬ তম এবং "good" এর অবস্থান ৯ । বিষয়টা একটু ঝামেলার হয়ে গেল । আমার আপনি সেটা ঠিক করতে বসলেন । এবং যথারীতি নাজেহাল অবস্থা ।
ওকে অনেক হয়েছে । আমরা প্রোগ্রামার মানুষজন এমনিতে অনেক অলস আর মাথা গরম টাইপের । এত ঝামেলার মাঝে যেন পড়া না লাগে সেজন্য আমরা শর্টকাট খুজি । তেমন একটা শর্টকাট হল টেস্ট ড্রাইভেন ডেভলপমেন্ট । বুঝতে সমস্যা হলেও ভয় পাওয়ার কোন কারন নেই । উপরের প্রবলেমটা একটু সহজ ভাবে চিন্তা করি চলুন । কয়েকটা ধাপে আমরা কাজটা করিঃ
ধাপ ১ঃ আমাদের বলা হয়েছে একটা টেক্সট ফাইল পড়ে তার মধ্য থেকে সবচেয়ে বেশি ফ্রিকোয়েন্সির নির্দিষ্ট কিছু শব্দ বাছাই করতে । এসবকিছু করতে গেলে প্রথমেইতো আমাদের টেক্সট ফাইলটি পরথে হবে তাইনা ? ওকে আমরা যে মেথড ( ফাংশন ) টি লিখছি সেটাতে কেবল টেক্সট ফাইলটি রিড করার কোড লিখলাম । এবার আমরা এই ছোট্ট কোডটুকু নানা ভাবে টেস্ট করলাম । দেখলাম এটি সব রকম সিচুয়েশন মিট করতে পারে কি না । ফাইলটি থাকলে রিড করতে পারছে কি না বা না থাকলে কি করা উচিৎ । ফাইলে কোন কনটেন্ট থাকলে কি করা উচিৎ বা না থাকলে কি করা উচিৎ এমন । এটুকু করলে অন্তত আমরা নিশ্চিত যে ফাইল পড়া নিয়ে আর কোন ঝামেলা থাকলো না । এবার আগাই সামনের দিকে ।
ধাপ ২ঃ যেহেতু আমাদের ফাইল রিড করা নিয়ে কোন চিন্তা আর নাই তাই আমরা নিশ্চিন্তে এবার সেখান থেকে কনটেন্ট পড়তে পারি । এবার আমরা একটা একটা করে শব্দ নিয়ে খেলা শুরু করে দিতে পারি । এমন একটা ডাটা স্ট্রাকচার নিয়ে কাজ করতে পারি যেখানে ২ টা ভাগ থাকবে । সি++ এর পেয়ার বা জাভার ম্যাপ বা সি এর স্ট্রাকচার বা নিজ থেকেও কাষ্টম ডাটা স্ট্রাকচার ডিজাইন করে নিতে পারেন । উদাহরন হিসাবে "Map<String, Integer> wordMap" এমনটা ধরে নিতে পারেন । এবার টেক্সট ফাইল থেকে একটা একটা শব্দ পড়লেন আর টেস্ট করলেন সেটা এই ম্যাপে আছে কি না । যদি না থাকে তবে কি হিসাবে ওই শব্দটি এবং ভ্যালু হিসাবে ১ ইনসার্ট করুন । যদি থাকে তবে সেই কি এর ভ্যালুর মান এক বাড়িয়ে দিন । এভাবে আমরা ওই ফাইলে যত শব্দ আছে তাদের ফ্রিকোয়েন্সি পেয়ে গেলাম । এবার টেস্ট করুন , আপনার কোডটি কি কাজ করছে ? হ্যা কাজ ঠিকই করছে তবে "Good" আর "good" এর মাঝে পার্থক্য করে ফেলেছে । কি আর করা সামনে আগাই ।
ধাপ ৩ঃ যেহেতু আগের ২ টা ধাপই সফলভাবে কাজ করছে তাই ওদিকে মাথা না ঘামালেও চলবে । এবার আমরা "Good" আর "good" এর মাঝে ব্যাবধানটা কমাতে হবে । একটা কাজ করলে কেমন হয় ? যদি আমরা যেকোন শব্দকেই আপার কেস বা লোয়ার কেসে কনভার্ট করে ফেলি ? মানে করলাম আমরা সবই লোয়ার কেসে কনভার্ট করবো , তাহলে "Good" = "good" এবং "good" = "good" হয়ে গেল । থাকলো আর কোন পার্থক্য ? না থাকারই কথা । এই ছোট্ট কাজটি আমরা করবো নতুন একটা ওয়ার্ড পড়ে সেটাকে ম্যাপে ইনসার্ট করার সময় এবং চেকিং এর সময় । এবার আমরা টেস্ট করলে দেখতে পাবো, নাহ এবার আর "Good" আর "good" এ গোলমাল হচ্ছে না । ওকে সামনে আগাই ।
ধাপ ৪ঃ কাজতো প্রায় শেষ । এবার আমরা ম্যাপটিকে ভ্যালুর রেসপেক্টে সর্ট করে ফেলতে পারি । সেটা কিভাবে করা হয় সেটা যদি না জেনে থাকেন তবে গুগলে একটু ঘাটাঘাটি করতে পারেন । এই লিংকে খুব সুন্দরভাবে বোঝানো হয়েছে কিভাবে একটি ম্যাপ টাইপ কালেকশন সর্ট করা যায় । অথবা কাষ্টম ডাটা টাইপের জন্য Comparator বা Comparable ইন্টারফেস নিসেও একটু পড়াশোনা করতে পারেন । ব্যাস হয়ে গেল সর্টিং । মনে করলাম ডিসেন্ডিং অর্ডারে সর্ট করেছেন । তাহলে প্রথম দিকের ১০ টি ( বা যতগুলা দেখাতে বলা হয়েছে ) দেখিয়ে দিন । টেস্ট করুন । আরেব্বাহ কাজ করছে তো ! কিন্তু সমস্যা হল ভিন্ন ভিন্ন শব্দ সংখ্যা যদি হয় ৭ টি আর আপনাকে যদি দেখাতে বলা হয় ১০ টি তাহলে তো একটু এক্সেপশন দিচ্ছেই । তাইনা ? ওকে সামনে আগাই ।
ধাপ ৫ঃ যেহেতু সব কাজই শেষ তাই বাড়তি করার মত যেটি থাকতে পারে সেটি হল যদি লিস্টের সাইজ প্রদত্ত নাম্বারের চেয়ে বড় হয় তাহলে কোন সমস্যা নাই ওই নাম্বার সংখ্যক ইটারেশন দিয়েই শব্দগুলা পিক করতে পারবেন । যদি ছোট হয় তাহলে লিস্টের সাইজ পর্যন্ত যান বা বলে দিন কাঙ্খিত নাম্বারের সমান পর্যান্ত শব্দ ওই টেক্সট ফাইলেই নেই । অথবা আপনার কাজের উপর ভিত্তি করে সিদ্ধান্ত নিন । ব্যাস কাজ শেষ !
উপরের ধাপগুলা অনুসরন করে আমরা দেখলাম খুব সহজে এবং বাগফ্রী একটি কোড কিভাবে লেখা যায় । এখানে পুরা কোডটি একবারে লিখে শেষে টেস্ট করতে গিয়ে মাথায় চুড় ছেড়ার কোন প্রয়োজন হয়নি । বরং খুব ছোট্ট ছোট্ট কাজকে বার বার টেস্ট করার মাধ্যমে আমরা আমাদের কাঙ্খিত ফলাফল পেয়ে গিয়েছি । সংক্ষেপে (ব্যাখ্যা অনেক বড় :P ) এটিই হল টেস্ট ড্রাইভেন ডেভলপমেন্ট । যেখানে প্রতিটি ছোট ছোট কাজকে সব রকম ভাবে টেস্ট করে দেখা হয় যে এই অংশটুকু তার চাওয়া পূরন করতে পারছে কি না । যতক্ষন না ওই অংশটুকু সম্পুর্ন শুদ্ধ না হচ্ছে ততক্ষন তার পরবর্তী অংশে হাত দেওয়া হচ্ছে না ।
আজ এই পর্যন্ত । আগামিতে টেস্ট ড্রাইভেন ডেভলপমেন্টের বিভিন্ত প্রসেস এবং বিভিন্ন টুলস নিয়ে আলোচনা করা হবে । আগামি পর্বের লিংক ।
সবাইকে ধন্যবাদ ।
No comments:
Post a Comment