পাঠ ৫৫ · ৫৭-এর মধ্যে · মডিউল ১৩
Home / Courses / Software Testing & Quality Assurance / কেস স্টাডি

কেস স্টাডি: একটি বাস্তব অ্যাপের জন্য টেস্টিং স্ট্র্যাটেজি

Case study: a testing strategy for a real-world app
১২ মিনিট পড়া উন্নত · Advanced Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • একটি বাস্তব ফিচারের বিভিন্ন অংশে কীভাবে বিভিন্ন টেস্ট টাইপ ম্যাপ করা হয় — একটি সম্পূর্ণ ওয়ার্কড উদাহরণ
  • কেন কোনো একটি একক টেস্ট টাইপ "যথেষ্ট" নয় — প্রতিটি লেয়ারের নিজস্ব শক্তি ও সীমাবদ্ধতা আছে
  • রিস্ক-ভিত্তিক অগ্রাধিকার (likelihood x impact) কীভাবে গণনা করে সীমিত সময়ে টেস্টিং-এর ক্রম ঠিক করা যায়
  • রিস্ক-ভিত্তিক ক্রম কেন একটি সাধারণ/নির্বিচার ক্রমের চেয়ে বাস্তবেই বেশি কার্যকর — একটি গণনা করা তুলনা

১ · দৃশ্যকল্প: ShoppyBazaar-এর চেকআউট ফ্লো

ধরা যাক "ShoppyBazaar" নামের একটি সম্পূর্ণ হাইপোথেটিক্যাল (কাল্পনিক, কোনো বাস্তব কোম্পানি নয়) ই-কমার্স অ্যাপের QA টিমকে দায়িত্ব দেওয়া হয়েছে তাদের চেকআউট ফ্লোর জন্য একটি সম্পূর্ণ টেস্টিং স্ট্র্যাটেজি ডিজাইন করার। ফ্লোটির প্রধান অংশগুলো হলো:

প্রাইসিং ও কুপন-ডিসকাউন্ট ইঞ্জিন
সাবটোটাল, ট্যাক্স, ও টায়ার্ড কুপন-ডিসকাউন্ট গণনার বিশুদ্ধ লজিক — কোনো I/O নেই।
পেমেন্ট-গেটওয়ে ইন্টিগ্রেশন
একটি তৃতীয়-পক্ষের পেমেন্ট প্রসেসরের সাথে যোগাযোগ — চার্জ করা, ব্যর্থতা হ্যান্ডল করা।
পুরো চেকআউট যাত্রা
ব্রাউজ করা থেকে শুরু করে কার্ট, ঠিকানা, পেমেন্ট, কনফার্মেশন পর্যন্ত সম্পূর্ণ ব্যবহারকারী-অভিজ্ঞতা।
ব্ল্যাক-ফ্রাইডে-স্টাইল ট্রাফিক
বছরের নির্দিষ্ট কয়েক দিনে স্বাভাবিকের বহুগুণ আকস্মিক ট্রাফিক স্পাইক।
পেমেন্ট ডেটা হ্যান্ডলিং
কার্ড/পেমেন্ট-সংক্রান্ত তথ্য কীভাবে গ্রহণ, প্রক্রিয়া, ও ট্রান্সমিট করা হচ্ছে তার নিরাপত্তা।

২ · কোন টেস্ট টাইপ কোন লেয়ারে

একটিমাত্র টেস্ট টাইপ দিয়ে পুরো ফ্লো "যথেষ্ট ভালোভাবে" যাচাই করা সম্ভব নয় — প্রতিটি অংশের প্রকৃতি ভিন্ন, তাই প্রতিটির জন্য সবচেয়ে উপযুক্ত টেস্ট টাইপও ভিন্ন। M7/L27-এর টেস্ট অটোমেশন পিরামিডের নীতি অনুযায়ী দ্রুত, বিচ্ছিন্ন ইউনিট টেস্ট সবচেয়ে বেশি সংখ্যায় থাকা উচিত, আর ধীর, ব্যয়বহুল E2E টেস্ট সবচেয়ে কম।

ইউনিট টেস্ট প্রাইসিং ও কুপন-ডিসকাউন্ট লজিক -- দ্রুত, বিচ্ছিন্ন, সংখ্যায় সবচেয়ে বেশি (M3) ইন্টিগ্রেশন / কন্ট্রাক্ট টেস্ট পেমেন্ট-গেটওয়ে ইন্টিগ্রেশনের "কন্ট্রাক্ট" যাচাই (M5/L20) E2E / সিস্টেম টেস্ট পুরো চেকআউট যাত্রা: ব্রাউজ -> কার্ট -> ঠিকানা -> পেমেন্ট -> কনফার্মেশন (M5/L21) পারফরম্যান্স টেস্ট ব্ল্যাক-ফ্রাইডে-স্টাইল আকস্মিক ট্রাফিক স্পাইকের বিরুদ্ধে লোড (M8) সিকিউরিটি টেস্ট পেমেন্ট ডেটা হ্যান্ডলিং, ইনপুট ভ্যালিডেশন, অথ (M9)
একই চেকআউট ফিচারের ভিন্ন ভিন্ন লেয়ারে ভিন্ন ভিন্ন টেস্ট টাইপ কাজ করে — এগুলো একে অপরের বিকল্প নয়, বরং পরিপূরক।
সহোদর কোর্সের সাথে সম্পর্ক

Full-Stack Web Frameworks ও Mobile App Development কোর্সেও একটি সংক্ষিপ্ত টেস্টিং-পিরামিড পাঠ আছে — সেগুলো এই একই পিরামিড ধারণা নির্দিষ্টভাবে ওয়েব বা মোবাইল প্রসঙ্গে প্রয়োগ করে, আর এই কোর্স টেস্টিং-এর সাধারণ, গভীর তত্ত্বটি শেখায়।

৩ · সীমিত সময়ে কোথা থেকে শুরু করব: রিস্ক-ভিত্তিক অগ্রাধিকার

বাস্তবে একই স্প্রিন্টে ফ্লোর সবগুলো এরিয়ার জন্য সম্পূর্ণ টেস্ট স্যুট বানানোর মতো সময় সবসময় থাকে না। তাই "কোনটা আগে?" প্রশ্নের উত্তর অনুমান দিয়ে নয়, M11/L49-এ প্রবর্তিত রিস্ক-ভিত্তিক অগ্রাধিকার প্যাটার্ন দিয়ে গণনা করে ঠিক করা হচ্ছে — প্রতিটি এরিয়ার জন্য সম্ভাবনা (likelihood, বাগ থাকার সম্ভাবনা কতটা) ও প্রভাব (impact, বাগ থাকলে ক্ষতি কতটা গুরুতর) ১-৫ স্কেলে ধার্য করে, ঝুঁকি স্কোর = সম্ভাবনা x প্রভাব হিসাবে গণনা করা হয়।

Python
# ShoppyBazaar চেকআউট ফ্লোর এরিয়াগুলো -- প্রতিটির সম্ভাবনা ও প্রভাব ১-৫ স্কেলে (দলের অভিজ্ঞতাভিত্তিক অনুমান)
CHECKOUT_AREAS = {
    "pricing_engine":           {"likelihood": 3, "impact": 5},
    "payment_gateway_contract": {"likelihood": 3, "impact": 5},
    "checkout_ui_flow":         {"likelihood": 4, "impact": 4},
    "coupon_engine":            {"likelihood": 4, "impact": 3},
    "black_friday_load":        {"likelihood": 2, "impact": 5},
    "payment_data_security":    {"likelihood": 2, "impact": 5},
    "order_confirmation_email": {"likelihood": 3, "impact": 2},
}

def risk_score(likelihood, impact):
    return likelihood * impact

scored = [
    (name, risk_score(data["likelihood"], data["impact"]))
    for name, data in CHECKOUT_AREAS.items()
]
ranked = sorted(scored, key=lambda pair: pair[1], reverse=True)

print(f"{'চেকআউট ফ্লো এরিয়া':28s} | ঝুঁকি স্কোর (সম্ভাবনা x প্রভাব)")
print("-" * 62)
for rank, (name, score) in enumerate(ranked, start=1):
    print(f"{rank}. {name:26s} | {score}")

    
লক্ষ্য করুন checkout_ui_flow সর্বোচ্চ ঝুঁকি স্কোর (১৬) পায় — কারণ এটি সবচেয়ে বেশি ব্যবহারকারী স্পর্শ করে (উচ্চ সম্ভাবনা) এবং ব্যর্থ হলে পুরো ক্রয়-প্রক্রিয়া আটকে যায় (উচ্চ প্রভাব)। black_friday_load ও payment_data_security-এর সম্ভাবনা কম (কম ঘন ঘন ঘটে) কিন্তু প্রভাব ভয়াবহ, তাই এগুলো এখনও উপরের দিকেই থাকে — শুধু সবচেয়ে ঘন ঘন ঘটা সমস্যাই "সবচেয়ে ঝুঁকিপূর্ণ" নয়।

৪ · রিস্ক-ভিত্তিক অগ্রাধিকারের প্রকৃত মূল্য

শুধু র‍্যাঙ্কিং দেখানো যথেষ্ট নয় — সীমিত ক্ষমতায় (ধরা যাক এই স্প্রিন্টে মাত্র ৪টি এরিয়ার জন্য পূর্ণাঙ্গ টেস্ট স্যুট বানানো সম্ভব) রিস্ক-ভিত্তিক ক্রম বনাম একটি সাধারণ (নাম অনুযায়ী বর্ণানুক্রমিক, ঝুঁকি-অজ্ঞ) ক্রম বেছে নিলে মোট ঝুঁকির কত শতাংশ প্রকৃতপক্ষে কভার হয়, তা এখানে সরাসরি গণনা করা হচ্ছে।

Python
total_risk = sum(score for _, score in scored)
top_n = 4

risk_based_covered = sum(score for _, score in ranked[:top_n])
risk_based_pct = round(100 * risk_based_covered / total_risk, 1)

naive_order = sorted(scored, key=lambda pair: pair[0])   # নামের বর্ণানুক্রমে -- ঝুঁকি বিবেচনা না করে
naive_covered = sum(score for _, score in naive_order[:top_n])
naive_pct = round(100 * naive_covered / total_risk, 1)

print(f"মোট চিহ্নিত ঝুঁকি স্কোরের যোগফল: {total_risk}")
print(f"রিস্ক-ভিত্তিক ক্রমে প্রথম {top_n}টি এরিয়া টেস্ট করলে কভার হয়: {risk_based_covered}/{total_risk} = {risk_based_pct}%")
print(f"শুধু বর্ণানুক্রমিক ক্রমে প্রথম {top_n}টি এরিয়া টেস্ট করলে কভার হতো: {naive_covered}/{total_risk} = {naive_pct}%")

    
একই সংখ্যক (৪টি) এরিয়া টেস্ট করেও রিস্ক-ভিত্তিক ক্রম মোট ঝুঁকির প্রায় ৬৯% কভার করে, অথচ নির্বিচার বর্ণানুক্রমিক ক্রমে মাত্র প্রায় ৫২% কভার হতো — একই পরিমাণ পরিশ্রমে উল্লেখযোগ্য বেশি ঝুঁকি কমানো যায় শুধু গণনা করে অগ্রাধিকার ঠিক করার মাধ্যমে, বিশেষ কোনো অতিরিক্ত টেস্ট না লিখেই।
মূল কথা · Key takeaway

একটি বাস্তব ফিচারের সম্পূর্ণ টেস্টিং স্ট্র্যাটেজি মানে "একটি টেস্ট টাইপ বেছে নেওয়া" নয় — বরং ফিচারের প্রতিটি অংশের প্রকৃতি বুঝে সঠিক টেস্ট টাইপ সঠিক লেয়ারে বসানো, এবং সীমিত সময়ে কোথা থেকে শুরু করা উচিত তা অনুমানের বদলে রিস্ক-ভিত্তিক গণনা দিয়ে ঠিক করা। এই দুটো সিদ্ধান্তই — "কোন টেস্ট টাইপ কোথায়" এবং "কোনটা আগে" — এই কোর্সের আগের প্রায় প্রতিটি মডিউলের ধারণা একসাথে ব্যবহার করে নেওয়া হয়।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ প্রাইসিং লজিকের জন্য ইউনিট টেস্ট যথেষ্ট মনে হলেও, পুরো চেকআউট যাত্রার জন্য কেন আলাদা করে একটি E2E টেস্টও দরকার?

ইউনিট টেস্ট প্রাইসিং ফাংশনটি বিচ্ছিন্নভাবে সঠিক কি না তা যাচাই করে, কিন্তু এটি নিশ্চিত করে না যে UI থেকে সঠিক মান পাস হচ্ছে, নেভিগেশন সঠিকভাবে কাজ করছে, বা পেমেন্ট গেটওয়ে থেকে ফেরত আসা কনফার্মেশন স্ক্রিনে সঠিক টোটাল দেখাচ্ছে কি না। E2E টেস্ট এই সবগুলো টুকরো একসাথে বাস্তবে ব্যবহারকারীর মতো করে কাজ করছে কি না তা যাচাই করে — দুটোই দরকার, একটি অন্যটির বিকল্প নয়।

প্র ০২ পেমেন্ট গেটওয়ে ইন্টিগ্রেশনের জন্য শুধু E2E টেস্টের ওপর নির্ভর না করে আলাদা করে একটি ইন্টিগ্রেশন/কন্ট্রাক্ট টেস্ট রাখার সুবিধা কী?

একটি তৃতীয়-পক্ষের পেমেন্ট গেটওয়ে সাধারণত ধীর, খরচযুক্ত (প্রতিটি টেস্ট কলে সত্যিকারের চার্জ হতে পারে), ও মাঝে মাঝে অনুপলব্ধ হতে পারে — এই বৈশিষ্ট্যগুলো একে E2E-এর প্রতিটি রানে জড়ানো অব্যবহারিক করে তোলে। একটি আলাদা কন্ট্রাক্ট টেস্ট (M5/L20) দ্রুত ও নির্ভরযোগ্যভাবে যাচাই করে যে ইন্টিগ্রেশনটি প্রত্যাশিত "চুক্তি" মেনে চলছে, গেটওয়েটিকে বারবার সত্যিকারভাবে না ডেকেই।

প্র ০৩ দলের কেউ বলছে, "আমরা তো এমনিতেই জানি কোনটা বেশি ঝুঁকিপূর্ণ, আলাদা করে স্কোর গণনার দরকার কী?" — এই যুক্তির সীমাবদ্ধতা কী?

অভিজ্ঞতাভিত্তিক অনুমান কার্যকর হতে পারে, কিন্তু এটি ব্যক্তিভেদে ভিন্ন হয়, দলে মতবিরোধ তৈরি করতে পারে, এবং সময়ের সাথে ভুলে যাওয়া বা পক্ষপাতদুষ্ট হওয়া সহজ। একটি স্পষ্ট গণনা করা স্কোর (এই পাঠের কোড সেলে যেমন দেখানো হয়েছে) সিদ্ধান্তটিকে স্বচ্ছ, পুনরাবৃত্তিযোগ্য, ও ব্যাখ্যাযোগ্য করে তোলে — নতুন কেউ দলে যোগ দিলেও একই যুক্তি অনুসরণ করতে পারে, এবং সংখ্যাগুলো (সম্ভাবনা/প্রভাব) পরিবর্তন হলে অগ্রাধিকারও স্বয়ংক্রিয়ভাবে আপডেট হয়।

অনুশীলন

  1. চিন্তা করুন: ShoppyBazaar-এর চেকআউট ফ্লোতে "গেস্ট চেকআউট" (লগইন ছাড়া কেনাকাটা) নামে একটি নতুন এরিয়া যোগ করতে হবে। আপনার মতে এর সম্ভাবনা ও প্রভাব স্কোর (১-৫) কত হওয়া উচিত, এবং কেন?

    যুক্তিসঙ্গত একটি ধারণা: সম্ভাবনা মাঝারি-বেশি (৩-৪, কারণ এটি একটি তুলনামূলক নতুন, কম-টেস্ট-করা পথ), প্রভাব মাঝারি (৩-৪, কারণ ব্যর্থ হলে কিছু ক্রেতা হারাতে পারে কিন্তু লগইন-করা ব্যবহারকারীরা প্রভাবিত হয় না)। সঠিক সংখ্যা গুরুত্বপূর্ণ নয় — গুরুত্বপূর্ণ হলো এই যুক্তিটি স্পষ্টভাবে লেখা, যাতে দলের অন্যরা এটি যাচাই বা চ্যালেঞ্জ করতে পারে।

  2. পরীক্ষা করুন: দ্বিতীয় কোড সেলে top_n = 4-কে top_n = 5-এ পরিবর্তন করে Run চেপে দেখুন রিস্ক-ভিত্তিক কভারেজ শতাংশ কতটা বাড়ে।

    পঞ্চম এরিয়া হিসেবে black_friday_load (স্কোর ১০) যোগ হবে (ট্রেতে থাকা সমান-স্কোরের এরিয়াগুলোর মধ্যে ranked লিস্টে যেটি আগে আসে), ফলে কভার হওয়া মোট স্কোর ৫৮ থেকে ৬৮-তে বেড়ে যাবে — অর্থাৎ মোট ঝুঁকির প্রায় ৮১% কভার হবে, ৫টি এরিয়া টেস্ট করেই।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • পরের পাঠ: সাধারণ টেস্টিং অ্যান্টি-প্যাটার্ন L56 একটি ভালো স্ট্র্যাটেজি থাকলেও বাস্তবায়নে কোন সাধারণ ভুলগুলো এড়ানো উচিত।
  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ টেস্ট ডিজাইন টেকনিক, ইউনিট টেস্টিং, টেস্ট ডাবলস, ইন্টিগ্রেশন, কভারেজ, অটোমেশন, পারফরম্যান্স ও সিকিউরিটি টেস্টিং, অ্যাডভান্সড টেকনিক, ম্যানেজমেন্ট, ও CI/CD ইন্টিগ্রেশন সহ সম্পূর্ণ কোর্স।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks, Mobile App Development, Ethics in Computing & AI Safety ও Software Testing & Quality Assurance — সব এক জায়গায়।
আগের পাঠ
CI/CD পাইপলাইনে কন্টিনিউয়াস টেস্টিং