আমি যখন আমার "সম্পন্ন" MERN-stack Zerodha ক্লোনটির বিরুদ্ধে Specmatic-এর contract test চালিয়েছিলাম, তখনই টুলটি এমন পাঁচটি আসল ত্রুটি (defects) শনাক্ত করেছিল যা আমার ম্যানুয়াল চেকিংয়ে ধরা পড়েনি। ১৭৮টি জেনারেট করা টেস্ট কেসের মধ্যে, এই টেস্ট স্যুটটি API-তে এমন সব সমস্যা তৈরি করেছিল যা বাস্তব ব্যবহারকারীদের ওপর প্রভাব ফেলত—যেমন ভুল ডেটা টাইপ (invalid data types), ভুল ক্রেডেনশিয়াল দিলে ক্র্যাশ হওয়া (crashes on malformed credentials), সাইলেন্ট ডেটা কারাপশন (silent data corruption), নন-আইডেমপোটেন্ট সাইন-আপ (non-idempotent sign-ups) এবং একটি ব্রেকিং কন্ট্রাক্ট পরিবর্তন (breaking contract change) যা CI গেটকে তৎক্ষণাৎ থামিয়ে দিয়েছিল।
কীভাবে বাগগুলো ম্যানুয়াল টেস্টিং থেকে বেঁচে গেল
এই প্রজেক্টটিতে একটি Node.js ব্যাকএন্ড, একটি React ফ্রন্ট-এন্ড, MongoDB স্টোরেজ এবং পেমেন্টের জন্য Razorpay ব্যবহার করা হয়েছিল। আমি ম্যানুয়ালি সাইন-আপ এবং পেমেন্ট ফ্লোগুলো পরীক্ষা করেছিলাম এবং সবকিছু ঠিকঠাক কাজ করছিল বলে মনে হয়েছিল। তবে, ম্যানুয়াল টেস্টিং শুধুমাত্র 'happy path' বা স্বাভাবিক পরিস্থিতিগুলো পরীক্ষা করে: এটি নিশ্চিত করে যে ব্যবহারকারীরা যখন নির্ধারিত ধাপগুলো অনুসরণ করেন তখন কোডটি সঠিকভাবে কাজ করছে। কিন্তু এটি প্রমাণ করে না যে সার্ভিসটি ভুল ফরম্যাটের রিকোয়েস্ট (malformed requests) বা অপ্রত্যাশিত ক্লায়েন্ট আচরণ সামলাতে সক্ষম কি না।
যখন আমি বিদ্যমান কোডের ওপর Specmatic প্রয়োগ করি, তখন 'contract'—যা প্রতিটি এন্ডপয়েন্টের রিকোয়েস্ট এবং রেসপন্স শেপের একটি সুনির্দিষ্ট বর্ণনা—সোর্স অফ ট্রুথ (source of truth) হিসেবে কাজ করে। এরপর টুলটি পজিটিভ এবং নেগেটিভ সিনারিও সম্বলিত একটি বিশাল ম্যাট্রিক্স স্বয়ংক্রিয়ভাবে তৈরি করে, যার অনেকগুলোই একজন ম্যানুয়াল টেস্টার হয়তো কখনোই চিন্তা করতে পারতেন না।
উন্মোচিত পাঁচটি ত্রুটি
- ইনপুট ভ্যালিডেশন গ্যাপ –
/newOrderএন্ডপয়েন্টটিquantityফিল্ডের জন্য দশমিক সংখ্যা এবং স্ট্রিং গ্রহণ করছিল, যদিও কন্ট্রাক্টে একটি integer চাওয়া হয়েছিল। ভুল টাইপ পাঠানো জেনারেট করা টেস্টগুলোর কারণে API ভুল আচরণ করছিল। - আনহ্যান্ডেলড লগইন এরর – অথেন্টিকেশন রুটে ভুল ফরম্যাটের ক্রেডেনশিয়াল দিলে একটি runtime exception তৈরি হচ্ছিল, কারণ কোডে টাইপ চেক ছিল না।
- সাইলেন্ট পেমেন্ট কারাপশন –
/verify-paymentএন্ডপয়েন্টটিamount-এর জন্য boolean ভ্যালু গ্রহণ করছিল। যখন একটিtrueভ্যালু চলে আসছিল, তখন ডেটাবেস শূন্য ভ্যালু দিয়ে একটি সফল পেমেন্ট রেকর্ড করছিল, যা নীরবে রেভিনিউ ফিগার বাড়িয়ে দিচ্ছিল। - আইডেমপোটেন্সি (Idempotency) অনুপস্থিত – টেস্ট স্যুটে সাইন-আপ ফ্লোটি দ্বিতীয়বার চালানোর সময় সেটি ব্যর্থ হয়েছিল, কারণ এন্ডপয়েন্টটি ডুপ্লিকেট ইউজারকে সুন্দরভাবে হ্যান্ডেল করার পরিবর্তে বিদ্যমান ইউজারকে পুনরায় তৈরি করার চেষ্টা করছিল।
- ব্রেকিং কন্ট্রাক্ট পরিবর্তন ধরা পড়া – আমি ইচ্ছাকৃতভাবে কন্ট্রাক্টে একটি ডেটা টাইপ পরিবর্তন করেছিলাম। CI পাইপলাইন তাৎক্ষণিকভাবে সেই পরিবর্তনটি প্রত্যাখ্যান করে এবং একটি ব্রেকিং রিলিজ রোধ করে।
CI পাইপলাইনের জন্য কেন কন্ট্রাক্ট টেস্টিং গুরুত্বপূর্ণ
- বৃহৎ পরিসরে নেগেটিভ টেস্টিং – ১৭৮টি কেসের বেশিরভাগই ছিল এজ-কেস (edge-case) ইনপুট। এগুলো হাতে লেখা অত্যন্ত সময়সাপেক্ষ হতো।
- থার্ড-পার্টি ক্লায়েন্টদের নিরাপত্তা – কন্ট্রাক্ট নির্ধারণ করে দেয় একটি সার্ভিস বাহ্যিক কনজিউমারদের কী প্রতিশ্রুতি দিচ্ছে। যদি ইমপ্লিমেন্টেশন পরিবর্তিত হয়, তবে কন্ট্রাক্ট টেস্টটি ব্যর্থ হবে এবং এর ফলে ডাউনস্ট্রিম অ্যাপগুলো সুরক্ষিত থাকবে।
- দ্রুত ফিডব্যাক লুপ – CI গেট একটি ব্রেকিং পরিবর্তন মার্জ হওয়ার আগেই থামিয়ে দিয়েছিল, যা টিমকে একটি ব্যয়বহুল রোলব্যাক থেকে বাঁচিয়েছে।
- কোডের গুণমান বৃদ্ধি – কন্ট্রাক্ট টেস্টযোগ্য করার জন্য একটি actuator এন্ডপয়েন্ট যোগ করা এবং সাইন-আপ ফ্লোকে idempotent করা ছিল প্রয়োজনীয় পদক্ষেপ, যা সার্ভিসটিকে আরও শক্তিশালী করেছে।
ডেভেলপারদের যে ভারসাম্য বজায় রাখা উচিত
কন্ট্রাক্ট টেস্টিং রক্ষণাবেক্ষণের বোঝা (maintenance overhead) বাড়িয়ে দেয়। স্পেসিফিকেশনটিকে অবশ্যই কোডের সাথে সামঞ্জস্যপূর্ণ থাকতে হয় এবং টেস্ট জেনারেশন প্রক্রিয়া বিল্ড টাইম বাড়িয়ে দিতে পারে। টিমগুলোকে সিদ্ধান্ত নিতে হবে যে এই বাড়তি নিরাপত্তা অতিরিক্ত প্রচেষ্টার তুলনায় যুক্তিযুক্ত কি না, বিশেষ করে ছোট প্রজেক্টের ক্ষেত্রে যেখানে ম্যানুয়াল টেস্টিং যথেষ্ট বলে মনে হয়।
ভবিষ্যতে যা লক্ষ্য রাখা উচিত
- ব্যাপক CI গ্রহণ – আরও বেশি টিম যখন তাদের পাইপলাইনে কন্ট্রাক্ট স্যুট ইন্টিগ্রেট করবে, তখন টুলগুলো সম্ভবত আরও দ্রুত এবং আরও কনফিগারযোগ্য হয়ে উঠবে।
- মানসম্মত কন্ট্রাক্ট ফরম্যাট – উদীয়মান স্পেসিফিকেশনগুলো বিভিন্ন সার্ভিস এবং টিমের মধ্যে কন্ট্রাক্ট শেয়ার করা সহজ করে তুলতে পারে।
- স্পেক আপডেটের অটোমেশন – কোড পরিবর্তন থেকে কন্ট্রাক্ট অনুমান করতে পারে এমন টুলগুলো ম্যানুয়াল রক্ষণাবেক্ষণের বোঝা কমিয়ে দিতে পারে।
আপনি যদি মনে করেন যে UI মসৃণভাবে চলছে বলে আপনার API-ও মজবুত, তবে একটি কন্ট্রাক্ট টেস্ট রান সেই লুকানো ত্রুটিগুলো প্রকাশ করতে পারে যা ম্যানুয়াল চেকিংয়ে ধরা পড়ে না। আপনার CI পাইপলাইনে একটি এক্সিকিউটেবল কন্ট্রাক্ট যোগ করা মানে "দেখতে ভালো লাগছে" থেকে "প্রমাণিত নিরাপদ" অবস্থায় পৌঁছানো।
Repository: https://github.com/priya3054/zerodha-specmatic
