Given-When-Then একটি কাঠামোগত প্যাটার্ন যা টেস্ট সিনারিও বর্ণনা করার জন্য, BDD দ্বারা domain-driven design থেকে নেওয়া এবং Behaviour-Driven Development-এর জন্য অভিযোজিত। ফরম্যাটটি সিনারিওকে তিনটি যৌক্তিক অংশে বিভক্ত করে: পূর্বশর্ত (Given), ক্রিয়া (When) এবং প্রত্যাশিত ফলাফল (Then)। Martin Fowler (2023)-এর মতে, Given-When-Then শুধু টেস্টের ফরম্যাট নয়, বরং একটি চিন্তার সরঞ্জাম যা বাস্তবায়ন শুরুর আগে প্রয়োজনীয়তা বিশ্লেষণ এবং সিনারিও ডিজাইনকে সুশৃঙ্খল করে।
মূল বিষয়
Given-When-Then একটি আচরণ বর্ণনার প্যাটার্ন, যা প্রথমে Dan North 2006 সালে Behavior-Driven Development পদ্ধতির অংশ হিসেবে প্রণয়ন করেন। প্যাটার্নটি টেস্ট সিনারিওর অগঠিত বর্ণনার সমস্যা সমাধান করে, যা প্রায়শই এলোমেলো ক্রমে পূর্বশর্ত, ক্রিয়া এবং যাচাইয়ের মিশ্রণ ধারণ করে।
প্যাটার্নের মূল ধারণা হল তিনটি ব্লকের মধ্যে দায়িত্ব পৃথকীকরণ। প্রতিটি ব্লক সিনারিওর ঠিক একটি দিকের জন্য দায়ী: আগের অবস্থা, চলাকালীন ইভেন্ট এবং পরবর্তী যাচাই। এটি সিনারিওকে পাঠযোগ্য, যাচাইযোগ্য এবং স্বয়ংক্রিয়যোগ্য করে তোলে। Cucumber ফ্রেমওয়ার্কের ডেভেলপারদের একটি গবেষণা (2024) অনুসারে, Given-When-Then প্যাটার্ন কঠোরভাবে অনুসরণকারী সিনারিওগুলি টিমের নতুন সদস্যের বুঝতে 42% কম সময় নেয়।
Dan North TDD-তে টেস্ট প্রণয়ন এবং Test-by-Example পদ্ধতি (Brian Marick দ্বারা তৈরি) থেকে ত্রি-অংশ কাঠামোর ধারণা নেন। মারিক উদাহরণ (examples) এর মাধ্যমে প্রয়োজনীয়তা বর্ণনা করার প্রস্তাব দেন যা একই সাথে টেস্ট হিসাবে কাজ করে। Given-When-Then এই ধারণাটিকে আনুষ্ঠানিক রূপ দেয়, অগঠিত উদাহরণগুলিকে পুনরাবৃত্তিযোগ্য প্যাটার্নে রূপান্তরিত করে।
Given-When-Then প্যাটার্ন শুধু Gherkin-এ BDD সিনারিওতেই নয়, বরং JUnit, XCTest এবং অন্যান্য ফ্রেমওয়ার্কে সাধারণ ইউনিট টেস্টেও প্রয়োগ করা হয়। কোডের মন্তব্য যা টেস্টকে তিনটি ব্লকে ভাগ করে — টেস্ট বেসের পাঠযোগ্যতা উন্নত করার জন্য একটি সাধারণ অনুশীলন। Google তার «Software Engineering at Google» (2020) বইয়ে এই পদ্ধতির সুপারিশ করে।
Given-When-Then-এর প্রতিটি ব্লকের কঠোরভাবে সংজ্ঞায়িত অর্থ এবং পূরণের নিয়ম রয়েছে। এই নিয়ম লঙ্ঘন করলে এমন সিনারিও তৈরি হয় যা স্বয়ংক্রিয় করা বা বোঝা কঠিন।
Given ব্লক পরীক্ষার অধীনে ক্রিয়া সম্পাদনের আগে সিস্টেমের অবস্থা বর্ণনা করে। এটি অন্তর্ভুক্ত করে: বিদ্যমান অবজেক্ট (ব্যবহারকারী, অর্ডার, সেটিংস), সক্রিয় অবস্থা (প্রমাণিত, নেটওয়ার্কে সংযুক্ত), এবং ডেটার প্রাথমিক মান। প্রতিটি Given যাচাইযোগ্য হতে হবে — যদি সিস্টেমের অবস্থা Given-এর সাথে না মেলে, তাহলে সিনারিওটি এড়িয়ে যেতে হবে বা টেস্ট পরিবেশ আগে থেকে প্রস্তুত করতে হবে।
When ব্লক একমাত্র ইভেন্ট বর্ণনা করে যা পরীক্ষার অধীনে আচরণ শুরু করে। এটি হতে পারে একটি মেথড কল, বাটন ক্লিক, নোটিফিকেশন বা সার্ভার থেকে উত্তর পাওয়া। মূল নিয়ম হল প্রতি সিনারিওতে একটি When। যদি ক্রিয়ার ক্রম যাচাই করার প্রয়োজন হয়, তাহলে পৃথক সিনারিও তৈরি করুন, When-এর চেইন নয়।
// Given: টেস্ট ডেটা তৈরি করি
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)
// When: ক্রিয়া সম্পাদন করি
val result = PurchaseUseCase().buy(user, product)
// Then: ফলাফল যাচাই করি
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)
Then ব্লক যাচাই করে যে সিস্টেম প্রত্যাশিত অবস্থায় পৌঁছেছে। এর মধ্যে অন্তর্ভুক্ত: প্রত্যাবর্তিত মান, অবজেক্টের অবস্থার পরিবর্তন, বাহ্যিক সার্ভিস কল (mock-verification এর মাধ্যমে), এবং UI পরিবর্তন। প্রতিটি Then ব্লকে একাধিক যাচাই থাকতে পারে, তবে সবগুলি একটি একক ক্রিয়ার সাথে সম্পর্কিত।
Given-When-Then এবং Arrange-Act-Assert (AAA) একই ত্রি-অংশ প্যাটার্নের দুটি সংস্করণ, কিন্তু ভিন্ন লক্ষ্য শ্রোতার সাথে। তাদের পার্থক্য বোঝা নির্দিষ্ট কাজের জন্য সঠিক ফরম্যাট নির্বাচন করতে সাহায্য করে।
| দিক | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| উৎপত্তি | BDD, ব্যবসায়িক বিশ্লেষণ | ইউনিট টেস্টিং |
| ভাষা | প্রাকৃতিক (Gherkin) | কোড (Kotlin, Swift, Java) |
| শ্রোতা | সম্পূর্ণ টিম + ক্লায়েন্ট | ডেভেলপার |
| বিস্তারিত স্তর | উচ্চ-স্তরের | বিস্তারিত |
| স্বয়ংক্রিয়করণ | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
Given-When-Then প্যাটার্ন সিনারিওর জন্য সর্বোত্তম যা ক্লায়েন্ট বা বিশ্লেষকের সাথে আলোচনা করা হয়: ফিচারের গ্রহণযোগ্যতার মানদণ্ড, ব্যবহারের ক্ষেত্রে, রিগ্রেশন পরীক্ষা। Gherkin সিনট্যাক্স প্রোগ্রামিং জ্ঞান ছাড়াই এই সিনারিওগুলি লিখতে দেয়।
Arrange-Act-Assert ইউনিট টেস্টের জন্য প্রাকৃতিক পছন্দ যা একটি নির্দিষ্ট মেথড বা ক্লাস যাচাই করে। AAA ফরম্যাট অতিরিক্ত ফ্রেমওয়ার্কের প্রয়োজন হয় না এবং যে কোনো প্রোগ্রামিং ভাষায় কাজ করে। iOS ডেভেলপমেন্টের জন্য, Apple XCTest ডকুমেন্টেশনে (2024) AAA সুপারিশ করে।
Android অ্যাপ্লিকেশনের জন্য Kotlin-এ Given-When-Then-এর ব্যবহারিক উদাহরণ দেখা যাক। প্রথম উদাহরণ — MockK ব্যবহার করে শপিং কার্ট টেস্টিং। দ্বিতীয় — পুশ নোটিফিকেশন লজিকের টেস্ট।
class CartTest {
fun `apply discount when total exceeds threshold`() {
// Given
val cart = Cart()
cart.addItem(Item("Laptop", price = 1000.0))
cart.addItem(Item("Mouse", price = 50.0))
val discount = DiscountCalculator(0.1)
// When
val total = discount.applyIfEligible(cart)
// Then
assertEquals(945.0, total)
assertTrue("Discount was not applied", total < 1050.0)
}
}
দ্বিতীয় উদাহরণটি অ্যাসিনক্রোনাস কোড সহ Given-When-Then প্রদর্শন করে। এখানে Given Firebase Cloud Messaging-এর অবস্থা নির্ধারণ করে, When — পুশ নোটিফিকেশন প্রাপ্তি, Then — প্রক্রিয়াকরণের যাচাই।
class PushNotificationTest {
fun `handle push notification when app in background`() = runTest {
// Given
val prefs = mockk<SharedPreferences>()
every { prefs.getString("token", null) } returns "fcm-token-abc"
val handler = PushHandler(prefs)
// When
val data = RemoteMessage().apply {
putData("type", "order_update")
putData("order_id", "123")
}
val result = handler.handleNotification(data)
// Then
assertEquals(NotificationAction.OpenOrder("123"), result)
}
}
তৃতীয় উদাহরণটি Gherkin-এ একটি BDD সিনারিও যা গ্রহণযোগ্যতা পরীক্ষার প্রসঙ্গে Given-When-Then দেখায়:
Feature: User Authorization
Scenario: User cannot login with expired token
Given the user has an expired refresh token
When they try to access the protected profile screen
Then they should see the login screen
And the app should clear all cached data
Given-When-Then-এর কার্যকর প্রয়োগের জন্য বেশ কয়েকটি প্রমাণিত অনুশীলন অনুসরণ করা প্রয়োজন। এগুলি সিনারিওর পাঠযোগ্যতা, রক্ষণাবেক্ষণযোগ্যতা এবং স্বয়ংক্রিয়করণ নিশ্চিত করে।
কঠোর নিয়ম: এক সিনারিও — একটি ক্রিয়া। যদি একাধিক When-এর ক্রম যাচাই করার প্রয়োজন হয়, তাহলে একাধিক সিনারিও তৈরি করুন যেখানে পূর্ববর্তীর ফলাফল পরবর্তীটির পূর্বশর্ত হয়। এটি সিনারিওকে পারমাণবিক এবং বোধগম্য করে।
Given-এর সারমর্ম বর্ণনা করা উচিত, নির্দিষ্ট সংখ্যা নয়। «Given ব্যবহারকারী ইভানভের ব্যালেন্স 500 রুবেল» — এর পরিবর্তে «Given পর্যাপ্ত ব্যালেন্স সহ ব্যবহারকারী»। নির্দিষ্ট ডেটা Examples টেবিল সহ Scenario Outline-এ স্থানান্তরিত হয়। এটি সিনারিওকে সর্বজনীন এবং পুনরায় ব্যবহারযোগ্য করে।
নিরবিচ্ছিন্ন ইন্টিগ্রেশন পাইপলাইনে Given-When-Then সিনারিওগুলিকে একীভূত করা তাদের ডকুমেন্টেশন থেকে রিগ্রেশনের বিরুদ্ধে সুরক্ষায় রূপান্তরিত করে। মোবাইল প্রজেক্টে প্রতিটি merge request স্বয়ংক্রিয়ভাবে BDD সিনারিও চালায় এবং কমপক্ষে একটি সিনারিও ব্যর্থ হলে একত্রিতকরণ ব্লক করে।
Android-এর জন্য Cucumber-এ BDD সিনারিও Gradle টাস্ক ./gradlew cucumber এর মাধ্যমে চালু হয়। iOS (Quick/Nimble) — xcodebuild test এর মাধ্যমে। CI সিস্টেমে (GitHub Actions, GitLab CI, Bitrise) BDD টেস্ট ইমুলেটর বা প্রকৃত ডিভাইসে সম্পাদিত হয়। রিপোর্ট HTML ফরম্যাটে তৈরি হয় যা ম্যানেজারদের বোধগম্য: সবুজ সিনারিও — পাস, লাল — ধাপ উল্লেখ সহ ব্যর্থ।
.feature ফাইলগুলি কোডের পাশে রিপোজিটরিতে সংরক্ষিত হয় এবং কোড রিভিউ এর মধ্য দিয়ে যায়। বিশ্লেষক ডেভেলপমেন্ট শুরুর আগে নতুন সিনারিও সহ merge request তৈরি করেন (BDD-first)। ডেভেলপার এই সিনারিওগুলিকে সবুজ করতে step definitions এবং বাস্তবায়ন লেখেন। যখন সব সিনারিও পাস হয় — ফাংশনালিটি প্রস্তুত। Gojko Adzic-এর «Specification by Example» (2011) বইয়ে বর্ণিত এই পদ্ধতি প্রয়োজনীয়তাকে কার্যকর আর্টিফ্যাক্টে রূপান্তরিত করে।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
গঠনের দিক থেকে, হ্যাঁ, এটি একই ত্রি-অংশ প্যাটার্ন। পার্থক্য শ্রোতার মধ্যে: Given-When-Then ব্যবসায়িক ভাষার দিকে ভিত্তিক এবং BDD-তে Gherkin-এর সাথে ব্যবহৃত হয়, আর Arrange-Act-Assert ইউনিট টেস্টের জন্য কারিগরি ফরম্যাট। পছন্দ প্রসঙ্গ এবং টিমের উপর নির্ভর করে।
কোনো সীমা নেই, তবে প্রতি Then-এর জন্য ৩–৫টির বেশি যাচাই না রাখা সুপারিশ করা হয়। যদি বেশি যাচাই থাকে, তাহলে সিনারিও সম্ভবত একটি ক্রিয়াতে অনেক বেশি যাচাই করছে। একে ভিন্ন Then সহ একাধিক সিনারিওতে ভাগ করুন।
না। প্যাটার্নটি যেকোনো টেস্ট ফ্রেমওয়ার্কে ব্যবহার করা যেতে পারে, শুধু টেস্টকে মন্তব্য বা খালি লাইন দিয়ে তিনটি ব্লকে বিভক্ত করে। Gherkin শুধুমাত্র প্রয়োজন যদি সিনারিও Cucumber বা SpecFlow-এর জন্য .feature ফাইল ফরম্যাটে লেখা হয়।
পুনরাবৃত্ত পূর্বশর্তগুলি Background (Gherkin) বা @Before মেথডে (JUnit) স্থানান্তর করার সুপারিশ করা হয়। যদি পূর্বশর্ত জটিল হয়, টেস্ট ডেটা তৈরির জন্য Builder প্যাটার্ন ব্যবহার করুন। এটি Given-কে সংক্ষিপ্ত এবং পাঠযোগ্য রাখে।
না। When একটি বাধ্যতামূলক ব্লক যা ক্রিয়া বর্ণনা করে। যদি সিনারিও শুধুমাত্র ক্রিয়া ছাড়া অবস্থা যাচাই করে (যেমন, «অ্যাপ্লিকেশন লোড হলে ডেটা ক্যাশে করা উচিত»), When ট্রিগার বর্ণনা করে: «যখন অ্যাপ্লিকেশন শুরু হয়»।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন