সিস্টেম টেস্টিং ও এন্ড-টু-এন্ড টেস্টিং
এই পাঠে যা শিখবেন
- সিস্টেম টেস্টিং কী এবং এটি ইন্টিগ্রেশন টেস্টিং থেকে স্কোপের দিক থেকে কীভাবে আলাদা
- এন্ড-টু-এন্ড (E2E) টেস্টিং কী — সম্পূর্ণ ব্যবহারকারী-যাত্রা যাচাই করার ধারণা
- কেন E2E টেস্ট মূল্যবান হলেও ধীরগতির ও ভঙ্গুর হতে পারে (টেস্ট অটোমেশন পিরামিডে এর অবস্থান, M7/L27-এ বিস্তারিত)
- একাধিক সাব-সিস্টেম চেইন করে একটি সত্যিকারের E2E সিনারিও টেস্ট লেখা ও চালানো
১ · সিস্টেম টেস্টিং — পুরো সিস্টেম, ব্যবহারকারীর দৃষ্টিকোণ
সিস্টেম টেস্টিং সিস্টেমটিকে একটি ব্ল্যাক-বক্স হিসেবে দেখে — ভেতরের কোন মডিউল কীভাবে কাজ করছে তা নিয়ে মাথা না ঘামিয়ে, শুধু "ইনপুট দিলে সিস্টেম প্রত্যাশিত আউটপুট দিচ্ছে কি না, রিকোয়ারমেন্ট অনুযায়ী" তা যাচাই করে। এর মানে সিস্টেম টেস্টিং প্রায়ই ফাংশনাল রিকোয়ারমেন্টের পাশাপাশি নন-ফাংশনাল দিকও (পারফরম্যান্স, সিকিউরিটি — M8-M9-এ বিস্তারিত) কভার করতে পারে, যদিও এই পাঠ মূলত ফাংশনাল সিস্টেম টেস্টিং-এ ফোকাস করছে।
Mobile App Development ও Full-Stack Web Frameworks কোর্সের টেস্টিং-পিরামিড পাঠে E2E টেস্টিংকে পিরামিডের সবচেয়ে উপরের, সবচেয়ে কম-সংখ্যক স্তর হিসেবে দেখানো হয়েছে সেই কোর্সগুলোর নির্দিষ্ট web/mobile প্রেক্ষাপটে — এই পাঠ সেই একই ধারণার সাধারণ, প্রযুক্তি-নিরপেক্ষ, গভীর সংস্করণ।
২ · একটি সত্যিকারের E2E সিনারিও টেস্ট
নিচের কোড সেলে চারটি ছোট stand-in ফাংশন সংজ্ঞায়িত করা হয়েছে — প্রতিটি একটি সাব-সিস্টেমের প্রতিনিধিত্ব করছে
(auth, catalog, cart, payment) — এবং M2/L09-এর মতোই একটি unittest.TestCase এই চারটিকে একটি
একক ব্যবহারকারী-যাত্রায় চেইন করে, প্রতিটি ধাপের ফলাফল প্রিন্ট করে ও assertEqual দিয়ে যাচাই করে।
import unittest
# --- চারটি সাব-সিস্টেমের stand-in ফাংশন ---
USERS = {"rahim": {"password": "secret123"}}
CATALOG = {
"sku1": {"name": "Keyboard", "price": 1200},
"sku2": {"name": "Mouse", "price": 500},
}
def authenticate(username, password):
user = USERS.get(username)
if user is None or user["password"] != password:
raise ValueError("ভুল ইউজারনেম বা পাসওয়ার্ড")
return {"username": username, "token": f"token-{username}"}
def get_product(sku):
if sku not in CATALOG:
raise KeyError(f"অজানা sku: {sku}")
return CATALOG[sku]
def add_to_cart(cart, sku, qty=1):
product = get_product(sku)
cart.append({"sku": sku, "name": product["name"], "price": product["price"], "qty": qty})
return cart
def calculate_total(cart):
return sum(item["price"] * item["qty"] for item in cart)
def process_payment(session_token, amount):
if not session_token.startswith("token-"):
raise ValueError("অথেন্টিকেশন ছাড়া পেমেন্ট করা যাবে না")
if amount <= 0:
raise ValueError("অবৈধ পরিমাণ")
return {"status": "success", "charged": amount}
# --- সম্পূর্ণ E2E সিনারিও টেস্ট ---
class EndToEndCheckoutTest(unittest.TestCase):
def test_full_purchase_journey(self):
# ধাপ ১: Auth
session = authenticate("rahim", "secret123")
self.assertEqual(session["username"], "rahim")
print("ধাপ ১ (Auth): লগইন সফল ->", session)
# ধাপ ২: Catalog
product = get_product("sku1")
self.assertEqual(product["name"], "Keyboard")
print("ধাপ ২ (Catalog): প্রোডাক্ট পাওয়া গেছে ->", product)
# ধাপ ৩: Cart
cart = []
add_to_cart(cart, "sku1", qty=2)
add_to_cart(cart, "sku2", qty=1)
total = calculate_total(cart)
self.assertEqual(total, 1200 * 2 + 500)
print("ধাপ ৩ (Cart): কার্ট ->", cart, "| মোট ->", total)
# ধাপ ৪: Payment
result = process_payment(session["token"], total)
self.assertEqual(result["status"], "success")
print("ধাপ ৪ (Payment): ফলাফল ->", result)
suite = unittest.TestLoader().loadTestsFromTestCase(EndToEndCheckoutTest)
unittest.TextTestRunner(verbosity=2).run(suite)
test_full_purchase_journey — চারটি সাব-সিস্টেমকেই একটানা
কল করছে, ঠিক যেভাবে একজন প্রকৃত ব্যবহারকারী লগইন করে, একটি প্রোডাক্ট দেখে, কার্টে যোগ করে, এবং চেকআউট করে।
প্রতিটি ধাপের মাঝে assertEqual নিশ্চিত করছে সেই ধাপের ফলাফল ঠিক আছে কি না — যদি কোনো একটি
সাব-সিস্টেম ভুল ডেটা দেয় (যেমন calculate_total ভুল যোগফল বের করলে), পুরো টেস্টটি ব্যর্থ হবে এবং
ঠিক কোন ধাপে সমস্যা তা প্রিন্ট আউটপুট থেকে সহজেই বোঝা যাবে।
সিস্টেম টেস্টিং পুরো ইন্টিগ্রেটেড সিস্টেমকে রিকোয়ারমেন্টের বিরুদ্ধে যাচাই করে, আর E2E টেস্টিং সেই যাচাইকে একজন প্রকৃত ব্যবহারকারীর সম্পূর্ণ যাত্রার আকারে করে। এই ধরনের টেস্ট সবচেয়ে বেশি আস্থা দেয় (পুরো সিস্টেম সত্যিই কাজ করছে) কিন্তু সবচেয়ে বেশি সময়ও নেয় ও সবচেয়ে ভঙ্গুর — তাই টেস্ট অটোমেশন পিরামিডে (M7/L27) এদের সংখ্যা ইচ্ছাকৃতভাবে কম রাখা হয়, ইউনিট টেস্টের তুলনায়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ সিস্টেম টেস্টিং ও ইন্টিগ্রেশন টেস্টিং (L19) এর মধ্যে স্কোপের পার্থক্য ঠিক কী?
ইন্টিগ্রেশন টেস্টিং সাধারণত দুই বা কয়েকটি মডিউল/সার্ভিসের মধ্যেকার ইন্টারফেস সঠিক কি না তা যাচাই করে — স্কোপ আংশিক। সিস্টেম টেস্টিং পুরো সিস্টেমকে (সব মডিউল, সব ইন্টিগ্রেশন একসাথে) একটি একক ইউনিট হিসেবে ধরে রিকোয়ারমেন্টের বিরুদ্ধে যাচাই করে — স্কোপ সম্পূর্ণ। ব্যবহারিকভাবে, ইন্টিগ্রেশন টেস্টিং সিস্টেম টেস্টিং-এর আগে ঘটে, যাতে ছোট ছোট সমস্যা তাড়াতাড়ি ধরা পড়ে।
প্র ০২
কোড সেলে যদি add_to_cart-এ একটি বাগ থাকতো যা qty উপেক্ষা করে সবসময় ১টি করে
যোগ করত, তাহলে কোন assertEqual ব্যর্থ হতো এবং কেন?
self.assertEqual(total, 1200 * 2 + 500) লাইনটি ব্যর্থ হতো। কারণ যদি add_to_cart
সবসময় qty=1 ধরে নিত, তাহলে sku1-এর জন্য প্রকৃত quantity ২ হওয়ার বদলে ১ হয়ে যেত,
ফলে calculate_total এর হিসাব হতো 1200 * 1 + 500 = 1700, প্রত্যাশিত
2900-এর বদলে — একটি স্পষ্ট, তাৎক্ষণিক ব্যর্থতা যা ঠিক কোন ধাপে (ধাপ ৩, Cart) সমস্যা তা
নির্দেশ করে।
প্র ০৩ E2E টেস্ট কেন সাধারণত ইউনিট টেস্টের চেয়ে ধীরগতির ও বেশি ভঙ্গুর হয়?
একটি E2E টেস্ট একসাথে একাধিক সাব-সিস্টেমের উপর নির্ভর করে (এখানে চারটি) — বাস্তব-জগতে এগুলো প্রায়ই নেটওয়ার্ক কল, ডেটাবেস বা তৃতীয়-পক্ষ সার্ভিস জড়িত থাকে, যা ইউনিট টেস্টের তুলনায় স্বাভাবিকভাবেই ধীর। এছাড়া, চারটির যেকোনো একটি সাব-সিস্টেমে সাময়িক সমস্যা (যেমন একটি ধীর নেটওয়ার্ক কল বা টাইমিং ইস্যু) হলে পুরো টেস্টটি ব্যর্থ হতে পারে, এমনকি মূল লজিক ঠিক থাকলেও — এই কারণেই M7/L30-এ "flaky test"-এর অন্যতম প্রধান উৎস হিসেবে E2E টেস্টকে দেখা হয়।
অনুশীলন
-
চিন্তা করুন: কোড সেলের সিনারিওতে যদি ব্যবহারকারী ভুল পাসওয়ার্ড দেয় (ধাপ ১-এই ব্যর্থ হয়),
তাহলে বাকি তিনটি ধাপ (catalog, cart, payment) কি আদৌ চলবে? কেন বা কেন নয়?
না —
authenticate()ভুল পাসওয়ার্ডে একটিValueErrorরেইজ করে, যা টেস্ট মেথডের ভেতরে ধরা (catch) হচ্ছে না, তাই টেস্ট মেথডটি তৎক্ষণাৎ সেখানেই থেমে যাবে এবংunittestএটাকে একটি ERROR হিসেবে রিপোর্ট করবে। বাকি তিনটি ধাপের কোড লাইনই কখনও এক্সিকিউট হবে না — এটাই একটি বাস্তব E2E টেস্টের স্বাভাবিক আচরণ, কারণ বাস্তব ব্যবহারকারীও লগইন ব্যর্থ হলে পরের ধাপে যেতে পারে না। -
পরীক্ষা করুন: কোড সেলে
test_full_purchase_journey-এর শুরুতেauthenticate("rahim", "wrong-password")দিয়ে পরীক্ষা করুন (আসল কলটি সাময়িকভাবে বদলে) — Run চেপে দেখুন টেস্ট রানার ঠিক কী রিপোর্ট করে।টেস্ট রানার
test_full_purchase_journey-কে একটি ERROR হিসেবে দেখাবে (FAIL নয়, কারণ এটি একটি অপ্রত্যাশিত exception, কোনোassertEqualব্যর্থতা নয়) — সাথেValueError: ভুল ইউজারনেম বা পাসওয়ার্ডসহ একটি ট্রেসব্যাক দেখাবে, এবং সামারিতে "FAILED (errors=1)" প্রদর্শিত হবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ টেস্ট ডিজাইন টেকনিক, ইউনিট টেস্টিং, টেস্ট ডাবলস, ইন্টিগ্রেশন টেস্টিং, কভারেজ, অটোমেশন, পারফরম্যান্স ও সিকিউরিটি টেস্টিং, অ্যাডভান্সড টেকনিক ও CI/CD ইন্টিগ্রেশন — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Mobile App Development কোর্স সহোদর কোর্স সেই কোর্সের টেস্টিং-পিরামিড পাঠে E2E টেস্টিং মোবাইল প্রেক্ষাপটে প্রয়োগ করা হয়েছে — এই কোর্স তার সাধারণ, গভীর সংস্করণ।
- সব 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 — সব এক জায়গায়।