রিগ্রেশন হল একটি বাগ যা কোডে পরিবর্তন আনার পর দেখা দেয়, যদিও আগে একই ফাংশনালিটি সঠিকভাবে কাজ করছিল। রিগ্রেশন মানে হল নতুন পরিবর্তনটি আগে যা লেখা এবং পরীক্ষা করা হয়েছিল তা «ভেঙে» দিয়েছে। এটি ডেভেলপমেন্টের সবচেয়ে সাধারণ এবং বিপজ্জনক সমস্যাগুলির মধ্যে একটি: একটি বাগ ঠিক করতে গিয়ে, ডেভেলপার অজান্তেই তিনটি অন্যান্য ফিচার ভেঙে দিতে পারে। Capers Jones Software Engineering 2023-এর মতে, রিগ্রেশন বাগের গড় ঘনত্ব হল প্রতি 100 পরিবর্তিত কোড লাইনে 1–3টি। আসুন রিগ্রেশনের কারণ, সনাক্তকরণের পদ্ধতি এবং প্রতিরোধের কৌশলগুলি বুঝি।
মূল পয়েন্ট
রিগ্রেশন হল এমন একটি পরিস্থিতি যেখানে পূর্ববর্তী সংস্করণে কাজ করা ফাংশনালিটি পরিবর্তন আনার পর কাজ করা বন্ধ করে দেয়। পরিবর্তন যে কোনো কিছু হতে পারে: বাগ ফিক্স, নতুন ফিচার যোগ করা, রিফ্যাক্টরিং, লাইব্রেরি আপডেট বা এমনকি কনফিগারেশন পরিবর্তন। রিগ্রেশন স্থিতিশীলতার প্রধান শত্রু: প্রতিটি পরিবর্তন এমন কিছু ভেঙে ফেলার ঝুঁকি নিয়ে আসে যা আগে যাচাই এবং প্রকাশিত হয়েছে।
শব্দটি টেস্টিং থেকে এসেছে: রিগ্রেশন টেস্টিং হল প্রতিটি পরিবর্তনের পর বিদ্যমান টেস্টগুলি পুনরায় চালানোর প্রক্রিয়া। যদি আগে পাস করা টেস্ট ব্যর্থ হয়, তাহলে রিগ্রেশন ঘটেছে। বিস্তৃত অর্থে, রিগ্রেশন শুধু টেস্ট ব্যর্থতা নয়, বরং ব্যবহারকারী বা QA-এর দ্বারা লক্ষ্য করা কোনো আচরণগত অবনতি। Tricentis State of Testing 2023-এর মতে, প্রোডাকশনে পাওয়া সমস্ত বাগের 35–45% রিগ্রেশন।
রিগ্রেশনকে সাধারণ বাগ থেকে আলাদা করে সময়ের প্রসঙ্গ: একটি বাগ সবসময়ই বিদ্যমান থাকতে পারে, যখন রিগ্রেশন সবসময় একটি পরিবর্তনের ফলাফল। এই পার্থক্যটি গুরুত্বপূর্ণ কারণ রিগ্রেশনের কারণ খুঁজতে «কাজ করছিল» এবং «কাজ করা বন্ধ করে দিয়েছে»-এর মধ্যে কী পরিবর্তন হয়েছে তা বিশ্লেষণ করে শুরু হয়। Git bisect রিগ্রেশন সৃষ্টিকারী কমিট খুঁজে বের করার মানক হাতিয়ার।
স্থানীয় রিগ্রেশন — মডিউল A-তে পরিবর্তন একই মডিউল A-তে ফাংশনালিটি ভেঙে দেয়। উদাহরণ: ডেভেলপার একটি সর্টিং ফাংশন পুনরায় লেখে এবং এটি খালি অ্যারে সঠিকভাবে হ্যান্ডেল করা বন্ধ করে দেয়। স্থানীয় রিগ্রেশন সনাক্ত এবং ঠিক করা সবচেয়ে সহজ কারণ কারণ এবং প্রভাব কাছাকাছি থাকে।
দূরবর্তী রিগ্রেশন — মডিউল A-তে পরিবর্তন মডিউল B-তে ফাংশনালিটি ভেঙে দেয়, যা কোড দ্বারা সরাসরি সংযুক্ত নয় কিন্তু ডেটা বা সময় দ্বারা সংযুক্ত। উদাহরণ: «ব্যবহারকারী» মডিউলে ডেটাবেস স্কিমা পরিবর্তন «অ্যানালিটিক্স» মডিউলে রিপোর্ট ভেঙে দেয় যা একই টেবিল ব্যবহার করে। দূরবর্তী রিগ্রেশন সবচেয়ে প্রতারণাপূর্ণ: ডেভেলপার সন্দেহ করে না যে তার পরিবর্তন অন্য মডিউলকে প্রভাবিত করবে।
পার্শ্ব-প্রতিক্রিয়া রিগ্রেশন — একটি পার্শ্ব প্রতিক্রিয়া (লগিং, ক্যাশিং, নোটিফিকেশন পাঠানো) পরিবর্তন প্রত্যাশিত আচরণ ভেঙে দেয়। উদাহরণ: ডেভেলপার গতি বাড়ানোর জন্য ক্যাশিং যোগ করে, কিন্তু পুরনো ক্যাশের কারণে ব্যবহারকারীরা পুরনো ডেটা দেখে। পার্শ্ব-প্রতিক্রিয়া রিগ্রেশন স্বয়ংক্রিয় টেস্ট দ্বারা ধরা কঠিন কারণ পার্শ্ব প্রতিক্রিয়া প্রায়ই টেস্ট দ্বারা আচ্ছাদিত হয় না।
পারফরম্যান্স রিগ্রেশন — কোড কার্যকরীভাবে সঠিকভাবে কাজ করতে থাকে কিন্তু আগের চেয়ে ধীর। উদাহরণ: নতুন এনক্রিপশন অ্যালগরিদম একই ফলাফল দেয়, কিন্তু নির্বাহের সময় 2 ms থেকে বেড়ে 200 ms হয়েছে। পারফরম্যান্স রিগ্রেশন সাধারণ ইউনিট টেস্ট দ্বারা ধরা পড়ে না — বেঞ্চমার্ক এবং প্রোফাইলিং প্রয়োজন।
| রিগ্রেশনের ধরন | উদাহরণ | সনাক্তকরণ পদ্ধতি |
|---|---|---|
| স্থানীয় | ভাঙা সর্টিং | ইউনিট টেস্ট |
| দূরবর্তী | DB স্কিমা পরিবর্তন | ইন্টিগ্রেশন টেস্ট |
| পার্শ্ব-প্রতিক্রিয়া | পুরনো ক্যাশ | E2E টেস্ট |
| পারফরম্যান্স | ধীর প্রতিক্রিয়া | বেঞ্চমার্ক |
প্রথম কারণ হল কোড কাপলিং। মডিউল যত বেশি একে অপরের উপর নির্ভরশীল, একটিতে পরিবর্তন অন্যটিতে রিগ্রেশন সৃষ্টি করার সম্ভাবনা তত বেশি। ক্লাসিক অ্যান্টি-প্যাটার্ন: গড অবজেক্ট (একটি অবজেক্ট যা সবকিছু করে), শটগান সার্জারি (এক জায়গায় পরিবর্তনের জন্য ডজনখানেক জায়গায় সম্পাদনা প্রয়োজন), সার্কুলার ডিপেন্ডেন্সি। কাপলিং কমানো হল আর্কিটেকচারের বিষয়: SOLID নীতি, ডিপেন্ডেন্সি ইনজেকশন, হেক্সাগোনাল আর্কিটেকচার।
দ্বিতীয় কারণ হল পরিবর্তিত ফাংশনালিটির জন্য টেস্টের অভাব। যদি কোড টেস্ট দ্বারা আচ্ছাদিত না হয়, তাহলে ডেভেলপার শুধু QA বা ব্যবহারকারীদের কাছ থেকে রিগ্রেশন সম্পর্কে জানতে পারে। Google Testing Blog-এর মতে, >75% টেস্ট কভারেজ সম্পন্ন প্রকল্পে <25% কভারেজ সম্পন্ন প্রকল্পের তুলনায় 5 গুণ কম রিগ্রেশন হয়। TDD (টেস্ট-ড্রিভেন ডেভেলপমেন্ট) নিশ্চিত করে যে টেস্ট কোডের আগে লেখা হয়, «যখন সময় হবে» না।
তৃতীয় কারণ হল মানবিক কারণ। ডেভেলপার সম্পর্কিত ফাংশনালিটি সম্পর্কে জানে না, সমস্ত নির্ভরতা বোঝে না বা কেবল তাড়াহুড়োয় থাকে। কারণ কোডবেস জ্ঞান ভাগাভাগির অভাব। সমাধান: অন্যান্য মডিউলের ডেভেলপারদের সাথে কোড রিভিউ, পেয়ার প্রোগ্রামিং, আর্কিটেকচার ডকুমেন্টেশন। প্রকল্পের বাস ফ্যাক্টর নথিভুক্ত আর্কিটেকচারাল সিদ্ধান্তের সংখ্যার ব্যস্তানুপাতিক।
রিগ্রেশন টেস্টিং হল প্রতিটি পরিবর্তনের পর পুরনো ফাংশনালিটি ভাঙেনি তা যাচাই করার জন্য বিদ্যমান টেস্টগুলি পুনরায় চালানোর প্রক্রিয়া। এটি নিশ্চিত করার একমাত্র উপায় যে একটি নতুন পরিবর্তন বিদ্যমান কোডকে ব্যাহত করেনি। রিগ্রেশন টেস্টিং ছাড়া, প্রতিটি রিলিজ একটি লটারি: ডেভেলপার আশা করে সে কিছু ভাঙেনি কিন্তু নিশ্চিত করতে পারে না।
ম্যানুয়াল রিগ্রেশন টেস্টিং সবচেয়ে ব্যয়বহুল এবং অকার্যকর পদ্ধতি। প্রকল্প বাড়ার সাথে সাথে রিগ্রেশন টেস্ট পরিস্থিতির সংখ্যা রৈখিকভাবে বাড়ে, যখন ম্যানুয়াল নির্বাহের সময় দ্রুতগতিতে বাড়ে। 2–3 বছর ডেভেলপমেন্টের পর, ম্যানুয়াল রিগ্রেশনে 2–3 সপ্তাহ লাগতে পারে, যা ঘন ঘন রিলিজ অসম্ভব করে তোলে। একমাত্র সমাধান অটোমেশন।
স্বয়ংক্রিয় রিগ্রেশন টেস্টিং টেস্ট পিরামিড অনুযায়ী স্তরে বিভক্ত:
Google Testing Blog-এর মতে, সর্বোত্তম অনুপাত 70% ইউনিট টেস্ট, 20% ইন্টিগ্রেশন টেস্ট, 10% E2E। এই অনুপাত থেকে বিচ্যুতি রিগ্রেশন টেস্টিংয়ের কার্যকারিতা কমায়: অত্যধিক E2E টেস্ট পাইপলাইন ধীর করে, খুব কম ইউনিট টেস্ট মাইক্রো-বাগ অলক্ষিত রেখে দেয়।
প্রথম কৌশল হল পূর্ণ রিগ্রেশন। প্রকল্পের সমস্ত টেস্ট চালানো হয়। সবচেয়ে নির্ভরযোগ্য কিন্তু সবচেয়ে ধীর পদ্ধতি। ছোট প্রকল্পের জন্য উপযুক্ত (10,000 টেস্ট পর্যন্ত, চলমান সময় <30 মিনিট)। বড় প্রকল্পের জন্য, পূর্ণ রিগ্রেশনে ঘন্টা লাগতে পারে, যা CI/CD পাইপলাইনকে অকার্যকর করে তোলে।
দ্বিতীয় কৌশল হল নির্বাচিত রিগ্রেশন। শুধু পরিবর্তিত কোডের সাথে সম্পর্কিত টেস্ট চালানো হয়। সম্পর্ক নির্ধারণের জন্য একটি কোড ডিপেন্ডেন্সি গ্রাফ ব্যবহার করা হয়। হাতিয়ার: Bazel (Google), Nx (JavaScript), sbt (Scala)। নির্বাচিত রিগ্রেশন 60–80% চলমান সময় বাঁচায় কিন্তু সঠিক ডিপেন্ডেন্সি গ্রাফ নির্মাণ প্রয়োজন — ত্রুটিগুলি এড়িয়ে যাওয়া রিগ্রেশন ঘটায়।
তৃতীয় কৌশল হল অগ্রাধিকার ভিত্তিক রিগ্রেশন। সমস্ত টেস্ট অগ্রাধিকার অনুযায়ী সাজানো হয়: ক্রিটিকাল পাথ (সবচেয়ে গুরুত্বপূর্ণ ব্যবহারকারী পরিস্থিতি), উচ্চ ঝুঁকি (বাগ ইতিহাস সহ কোড), পরিবর্তিত কোড (পরিবর্তন দ্বারা প্রভাবিত কোড)। প্রথমে সর্বোচ্চ অগ্রাধিকার টেস্ট চালানো হয় — যদি সেগুলি পাস করে, ডেভেলপার দ্রুত প্রতিক্রিয়া পায়। সময়-সীমিত নির্বাহ: ক্রিটিকাল টেস্ট 10 মিনিটে পরীক্ষা করা হয়, বাকি ব্যাকগ্রাউন্ডে চলে।
প্রথম এবং সবচেয়ে গুরুত্বপূর্ণ পদক্ষেপ হল টেস্ট লেখার সংস্কৃতি। প্রতিটি পরিবর্তনের সাথে একটি টেস্ট থাকা উচিত যা যাচাই করে পরিবর্তন কাজ করে এবং একটি টেস্ট যা যাচাই করে কিছু ভাঙেনি। TDD (টেস্ট-ড্রিভেন ডেভেলপমেন্ট) সর্বোত্তম ফলাফল দেয়: ডেভেলপার প্রথমে একটি ব্যর্থ টেস্ট লেখে, তারপর কোড যা এটি পাস করায়। এটি নিশ্চিত করে যে টেস্ট কোডের আগে বিদ্যমান।
দ্বিতীয় পদক্ষেপ হল বাধ্যতামূলক টেস্ট নির্বাহ সহ CI/CD পাইপলাইন। যতক্ষণ না সমস্ত টেস্ট পাস করে, পুল রিকোয়েস্ট মার্জ করা যায় না। জরুরিতার কারণে টেস্ট «বাদ» দেওয়া যায় না — জরুরি পরিবর্তন দ্রুততর কিন্তু বাধ্যতামূলক টেস্ট স্যুটের মধ্য দিয়ে যায়। Google DevOps Research-এর মতে, বাধ্যতামূলক CI/CD সম্পন্ন দলে প্রোডাকশনে 3 গুণ কম রিগ্রেশন হয়।
তৃতীয় পদক্ষেপ হল প্রোডাকশন মনিটরিং। সেরা টেস্টও রিগ্রেশনের বিরুদ্ধে 100% সুরক্ষা নিশ্চিত করে না। অবজারভেবিলিটি হাতিয়ার (Sentry, Datadog, New Relic) প্রতিটি ডিপ্লয়মেন্টের পরে মূল মেট্রিক ট্র্যাক করবে: ত্রুটি হার, লেটেন্সি, থ্রুপুট। সীমা অতিক্রম করলে স্বয়ংক্রিয় রোলব্যাক একটি সুরক্ষা জাল যদি রিগ্রেশন প্রোডাকশনে পৌঁছেও যায়।
চতুর্থ পদক্ষেপ হল রিগ্রেশন মানসিকতা সহ কোড রিভিউ। পর্যালোচককে জিজ্ঞাসা করা উচিত: «এই পরিবর্তনে আর কোন মডিউল ভেঙে যেতে পারে?». শুধু কোড সঠিক কিনা তা পরীক্ষা করা যথেষ্ট নয় — এটি সম্পর্কিত ফাংশনালিটি ব্যাহত করবে কিনা তা পরীক্ষা করা প্রয়োজন। কোড রিভিউ চেকলিস্টে «সম্পর্কিত মডিউলে রিগ্রেশন পরীক্ষা» আইটেম অন্তর্ভুক্ত করা উচিত।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
রিগ্রেশন হল একটি বাগ যা আগে ছিল না। সাধারণ বাগ ফিচার তৈরির সময় থেকে বিদ্যমান থাকতে পারে। রিগ্রেশন সবসময় একটি নির্দিষ্ট পরিবর্তনের সাথে যুক্ত — এটি কারণ খুঁজতে git bisect ব্যবহারের অনুমতি দেয়।
git bisect ব্যবহার করুন: যেখানে সবকিছু কাজ করছিল সেই কমিট এবং যেখানে ভেঙেছে সেই কমিট উল্লেখ করুন। Git ইতিহাসে বাইনারি সার্চ করে এবং রিগ্রেশন সৃষ্টিকারী কমিট খুঁজে বের করে। এটি হাজার হাজার কমিট সম্পন্ন বড় প্রকল্পের জন্যও কাজ করে।
কোনো নির্দিষ্ট সংখ্যা নেই, তবে একটি অভিজ্ঞতামূলক নিয়ম আছে: মূল ব্যবহারকারী ফ্লো-এর কভারেজ 100% হওয়া উচিত, সমস্ত ফাংশনের কভারেজ কমপক্ষে 70%। গুণমান পরিমাণের চেয়ে বেশি গুরুত্বপূর্ণ: একটি টেস্ট যা এজ কেস পরীক্ষা করে, হ্যাপি পাথে দশটি টেস্টের চেয়ে বেশি মূল্যবান।
হ্যাঁ, এবং এটিকে ইনফ্রাস্ট্রাকচার রিগ্রেশন বলে। OS আপডেট, ডেটাবেস ভার্সন পরিবর্তন, SSL সার্টিফিকেট আপডেট বা ওয়েব সার্ভার কনফিগারেশন পরিবর্তন কাজ করা কোড ভেঙে দিতে পারে। IaC (ইনফ্রাস্ট্রাকচার অ্যাজ কোড) এবং ইনফ্রাস্ট্রাকচার টেস্টিং (Test Kitchen, Terratest) এই ধরনের রিগ্রেশন ধরতে সাহায্য করে।
একটি ক্রিটিকাল ইউজার ফ্লো দিয়ে শুরু করুন। সবচেয়ে গুরুত্বপূর্ণ পরিস্থিতির (লগইন, চেকআউট) জন্য একটি স্বয়ংক্রিয় টেস্ট লিখুন। ডেমোতে দেখান কীভাবে টেস্ট রিগ্রেশন ধরে। টিম যখন সুবিধা দেখবে, তখন ধীরে ধীরে কভারেজ বাড়ান।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন