Fake হল একটি নির্ভরতার কার্যকরী সরলীকৃত বাস্তবায়ন যা একটি বাস্তব উপাদানের মতো আচরণ করে, কিন্তু উৎপাদন অবকাঠামোর পরিবর্তে ইন-মেমরি স্টোরেজ বা অন্যান্য হালকা প্রক্রিয়া ব্যবহার করে। Stub-এর বিপরীতে, fake-এ বাস্তব ব্যবসায়িক যুক্তি থাকে — সাজানো, ফিল্টার করা, একত্রিত করা — তবে বাহ্যিক প্রভাব ছাড়াই। Room-এর পরিবর্তে ইন-মেমরি ডেটাবেস বা SharedPreferences-এর পরিবর্তে HashMap হল ক্লাসিক উদাহরণ। আরও বিস্তারিত Martin Fowler-এর test doubles শ্রেণীবিভাগ-এ।
মূল বিষয়
Fake হল একটি ইন্টারফেসের পূর্ণ কিন্তু হালকা বাস্তবায়ন যা পরীক্ষণের জন্য উপযুক্ত। শব্দটি Gerard Meszaros (2007) “xUnit Test Patterns” বইয়ে প্রবর্তন করেছিলেন। Stub-এর বিপরীতে, যা হার্ডকোডেড উত্তর ফেরত দেয়, fake-এ কার্যকরযোগ্য কোড থাকে: এটি একটি তালিকা সাজাতে পারে, শর্ত অনুযায়ী ফিল্টার করতে পারে, রেকর্ড গণনা করতে পারে। উৎপাদন বাস্তবায়ন থেকে একমাত্র পার্থক্য হল যে fake ইন-মেমরি ডেটা নিয়ে কাজ করে এবং বাস্তব I/O অপারেশন করে না।
প্রধান সুবিধা হল গতি। Fake-এর সাথে পরীক্ষণগুলি মিলিসেকেন্ডে সম্পাদিত হয় কারণ ডিস্ক, নেটওয়ার্ক বা ডেটাবেসে অ্যাক্সেস থাকে না। একটি ইন-মেমরি HashMap Room বা CoreData-এর তুলনায় 100–1000 গুণ দ্রুত কাজ করে। একই সময়ে, fake বাস্তব ব্যবসায়িক যুক্তি পরীক্ষা করে: সাজানো, ফিল্টার করা, একত্রিত করা — যা কিছু stub পরীক্ষা করতে পারে না কারণ stub শুধু যা বলা হয়েছে তা ফেরত দেয়। Fake আত্মবিশ্বাস দেয় যে কোড ডেটা সঠিকভাবে প্রক্রিয়া করে, শুধু একটি পূর্বনির্ধারিত উত্তর পাওয়ার পরিবর্তে।
Fake Stub-এর চেয়ে ভাল — যদি পরীক্ষাধীন উপাদান ডেটার উপর একাধিক অপারেশন করে (পুনরুদ্ধার, ফিল্টার, সাজানো, সংরক্ষণ), তাহলে stub-কে প্রতিটি কল আলাদাভাবে কনফিগার করতে হবে। Fake-এ যুক্তি নিজের ভিতরে থাকে — পরীক্ষণটি কেবল পদ্ধতি কল করে এবং ফলাফল যাচাই করে। IT Sectr-এ, আমরা ইউনিট পরীক্ষণে সমস্ত রিপোজিটরির জন্য fakes ব্যবহার করি: একটি HashMap সহ fake রিপোজিটরি Mockito বা MockK সেটআপ না করেই 90% পরিস্থিতি কভার করে।
নির্বাচনের মানদণ্ড — নির্ধারণ করুন পরীক্ষণ কী যাচাই করে: অবস্থা নাকি মিথস্ক্রিয়া। যদি পরীক্ষণ অবস্থা (কাজের ফলাফল) যাচাই করে এবং যুক্তি ব্যবহার করে — fake ব্যবহার করুন। যদি পরীক্ষণে শুধুমাত্র যুক্তি ছাড়া ইনপুট ডেটা প্রয়োজন — stub যথেষ্ট। যদি পরীক্ষণ যাচাই করে যে একটি পদ্ধতি কল করা হয়েছিল — mock ব্যবহার করুন। একটি পরীক্ষণে test doubles-এর প্রকার মিশ্রিত করা বোঝা জটিল করে এবং ভঙ্গুরতা বাড়ায়।
| মানদণ্ড | Fake | Stub | Mock |
|---|---|---|---|
| যুক্তি আছে | হ্যাঁ (সরলীকৃত) | না | না |
| গতি | উচ্চ | সর্বোচ্চ | উচ্চ |
| আচরণ যাচাই | পরোক্ষ | না | হ্যাঁ (verify) |
| রক্ষণাবেক্ষণ | প্রতি ইন্টারফেসে একটি ক্লাস | প্রতি পরীক্ষণে কনফিগার | প্রতি পরীক্ষণে কনফিগার |
| বাস্তবতা | উচ্চ (কোড কাজ করে) | নিম্ন (হার্ডকোডেড ডেটা) | মধ্যম |
| মিথ্যা পজিটিভ ঝুঁকি | নিম্ন | মধ্যম | উচ্চ (ভঙ্গুর পরীক্ষণ) |
অ্যান্টি-প্যাটার্ন: Fake যা fake নয় — একটি সাধারণ ভুল যখন একজন ডেভেলপার একটি অবজেক্টকে fake বলে যা আসলে stub বা mock। যদি আপনার InMemoryUserRepository-এ কোনো যুক্তি (ফিল্টারিং, সাজানো) না থাকে — এটি fake নয়, বরং ইন-মেমরি স্টোরেজ সহ একটি stub। Fake stub থেকে কার্যকরযোগ্য যুক্তির উপস্থিতির দ্বারা আলাদা। যদি একটি fake রিপোজিটরি কেবল যা রাখা হয়েছিল তা ফেরত দেয় এবং ডেটা প্রক্রিয়া না করে — mock বা stub ব্যবহার করুন।
ব্যবহারিক সুপারিশ — প্রতিটি রিপোজিটরি বা পরিষেবার জন্য fake দিয়ে শুরু করুন। যদি fake 50 লাইনের বেশি হয় — এটি একাধিক ক্লাসে ভাগ করুন। যদি fake-এর একেবারেই প্রয়োজন না হয় (পরীক্ষণ শুধুমাত্র নির্দিষ্ট ডেটা সহ একটি দৃশ্যকল্প যাচাই করে) — stub ব্যবহার করুন। যদি পরীক্ষণ যাচাই করে যে একটি পদ্ধতি নির্দিষ্ট প্যারামিটার সহ কল করা হয়েছিল — mock ব্যবহার করুন। আগে থেকেই নির্বাচন অপ্টিমাইজ করবেন না: একটি fake লিখুন, এবং যদি এটি অতিরিক্ত হয়, একটি নির্দিষ্ট পরীক্ষণে এটি stub দিয়ে প্রতিস্থাপন করুন।
Room-এর জন্য Fake রিপোজিটরি — Android-এ fake-এর একটি সাধারণ উদাহরণ। UserRepository-এর উৎপাদন বাস্তবায়ন SQLite কোয়েরি সহ Room DAO ব্যবহার করে। Fake সংস্করণ MutableList বা HashMap-এ ডেটা সংরক্ষণ করে এবং একই পদ্ধতি প্রয়োগ করে: getUser(id), saveUser(user), deleteUser(id)। Fake-এ অনুসন্ধান, ফিল্টারিং এবং সাজানোর যুক্তি থাকে — উৎপাদন রিপোজিটরির মতো, কিন্তু SQL ছাড়া। এটি Room ডেটাবেস সেটআপ না করেই ViewModel এবং UseCase পরীক্ষণ করতে দেয়।
class FakeUserRepository : UserRepository {
private val users = mutableListOf<User>()
override suspend fun getUser(id: String): User? {
return users.find { it.id == id }
}
override suspend fun saveUser(user: User) {
val index = users.indexOfFirst { it.id == user.id }
if (index >= 0) users[index] = user
else users.add(user)
}
override suspend fun search(query: String): List<User> {
return users.filter {
it.name.contains(query, ignoreCase = true)
}
}
}
Retrofit API-এর জন্য Fake — MockWebServer-এর (যা একটি stub, fake নয়) পরিবর্তে, আপনি একটি ApiService বাস্তবায়ন তৈরি করতে পারেন যা একটি ইন-মেমরি সংগ্রহ থেকে ডেটা ফেরত দেয়। পার্থক্য: MockWebServer HTTP আটকায় এবং JSON ফেরত দেয়, যখন একটি fake ApiService সিরিয়ালাইজেশন ছাড়াই Kotlin ইন্টারফেস স্তরে কাজ করে। Fake দ্রুততর (কোনো JSON পার্সিং নেই) এবং ডিবাগ করা সহজ (একই প্রক্রিয়ায় চলে, টাইপ করা)। সেই পরীক্ষণের জন্য উপযুক্ত যেখানে HTTP সিম্যান্টিক্স (স্ট্যাটাস কোড, হেডার) গুরুত্বপূর্ণ নয়।
Swift-এ Fake — প্রোটোকলের মাধ্যমে তৈরি করা হয়। উৎপাদন ক্লাস বাস্তব যুক্তি (CoreData, URLSession) সহ প্রোটোকল প্রয়োগ করে। Fake স্ট্রাকচার ইন-মেমরি স্টোরেজ এবং সরলীকৃত যুক্তি সহ একই প্রোটোকল প্রয়োগ করে। Swift একটি মান সিম্যান্টিক্স的语言, তাই fake স্ট্রাকচারগুলি অপরিবর্তনীয় এবং মাল্টিথ্রেডেড পরীক্ষণে নিরাপদ। এটি Android অ্যানালগগুলির উপর একটি সুবিধা দেয়: ইন-মেমরি ডেটাতে অ্যাক্সেস সিঙ্ক্রোনাইজ করার প্রয়োজন নেই।
protocol UserRepositoryProtocol {
func getUser(id: String) async -> User?
func saveUser(user: User) async
}
final class FakeUserRepository: UserRepositoryProtocol {
private var storage: [String: User] = [:]
func getUser(id: String) async -> User? {
return storage[id]
}
func saveUser(user: User) async {
storage[user.id] = user
}
}
final class UserViewModelTests: XCTestCase {
func test_save_and_load() async {
let fake = FakeUserRepository()
let vm = UserViewModel(repository: fake)
let user = User(id: "1", name: "Alice")
await vm.saveUser(user)
let loaded = await vm.getUser(id: "1")
XCTAssertEqual(loaded?.name, "Alice")
}
}
CoreData-এর জন্য Fake — iOS প্রজেক্টে, আপনি description.type = NSInMemoryStoreType সেট করে একটি ইন-মেমরি NSPersistentContainer তৈরি করতে পারেন। এটি একটি সম্পূর্ণ CoreData স্ট্যাক, কিন্তু মেমরিতে চলছে। এই ধরনের fake SQLite ফাইল তৈরি না করেই NSFetchRequest, প্রেডিকেট এবং সাজানো পরীক্ষণ করতে দেয়। গতি: ইন-মেমরি CoreData-তে পরীক্ষণ ডিস্ক-ভিত্তিক অ্যানালগের তুলনায় 5–10 গুণ দ্রুত চলে। অসুবিধা: প্রতিবার NSManagedObjectModel সেটআপ করতে হবে।
FakeURLProtocol — iOS-এ নেটওয়ার্ক অনুরোধ আটকানোর জন্য URLProtocol-এর একটি উপশ্রেণী। এটি URLProtocol.registerClass(fakeProtocol) এর মাধ্যমে নিবন্ধিত হয়। অভ্যন্তরীণভাবে এতে একটি ইন-মেমরি URL -> Data অভিধান থাকে এবং বাস্তব অনুরোধ ছাড়াই ডেটা ফেরত দেয়। Stub থেকে পার্থক্য: FakeURLProtocol অনুরোধের বডি, হেডার পরীক্ষা করতে পারে এবং ইনপুট ডেটার উপর নির্ভর করে বিভিন্ন প্রতিক্রিয়া ফেরত দিতে পারে। এটি একটি fake কারণ এতে অনুরোধ রাউটিং যুক্তি রয়েছে।
Fake একটি Test Fixture হিসেবে — একটি ভাগ করা পরীক্ষণ মডিউলে (androidTest/sharedTest বা TestSupport) fake ক্লাস রাখুন। প্রজেক্টের সমস্ত পরীক্ষণ একই InMemoryUserRepository ব্যবহার করে। এটি প্রতিটি পরীক্ষণে mock অবজেক্ট সেটআপের পুনরাবৃত্তি দূর করে এবং অভিন্ন আচরণের নিশ্চয়তা দেয়। Fake-এর যুক্তি পরিবর্তন করা সমস্ত পরীক্ষণকে একসাথে আপডেট করে। IT Sectr-এ, আমরা fake ক্লাস sharedTest/java/com/itSectr/fake/-এ সংরক্ষণ করি এবং implementation project(:sharedTest) এর মাধ্যমে অন্তর্ভুক্ত করি।
পূর্বনির্ধারিত ডেটা সহ Fake — প্রায়শই পরীক্ষণে এমন একটি রিপোজিটরি প্রয়োজন যা ইতিমধ্যে কিছু রেকর্ড ধারণ করে। সমাধান: একটি ফ্যাক্টরি পদ্ধতি fakeWithData(vararg items) বা একটি বিল্ট-ইন addDefaultData() পদ্ধতি। ফ্যাক্টরি একটি fake তৈরি করে, এটি সাধারণ ডেটা দিয়ে পূর্ণ করে এবং ব্যবহারের জন্য প্রস্তুত একটি অবজেক্ট ফেরত দেয়। এটি পরীক্ষণে বয়লারপ্লেট হ্রাস করে: mock কল সেটআপ করার পরিবর্তে, পরীক্ষণটি কেবল FakeUserRepository.withUsers(alice, bob) কল করে।
কল গণনা সহ Fake — কখনও কখনও শুধু অবস্থা নয়, কলের সংখ্যাও যাচাই করার প্রয়োজন হয়। Fake-এ কাউন্টার থাকতে পারে: saveCallCount, getUserCallCount। পরীক্ষণটি সম্পাদনের পরে কাউন্টার যাচাই করে। এটি একটি বিশুদ্ধ fake (অবস্থা যাচাই) এবং mock (মিথস্ক্রিয়া যাচাই) এর মধ্যে একটি সমঝোতা। কাউন্টারগুলি আর্গুমেন্ট বা কল ক্রম যাচাই করে না — শুধু সংখ্যা। আর্গুমেন্ট যাচাইয়ের জন্য, mock ব্যবহার করুন।
Callback সহ Fake — অ্যাসিঙ্ক্রোনাস দৃশ্যকল্প পরীক্ষণের জন্য, fake প্রতিটি কলেই একটি callback গ্রহণ করতে পারে: beforeGetUser, afterSaveUser। এটি বিলম্ব, ত্রুটি অনুকরণ করতে বা মধ্যবর্তী অবস্থা পরীক্ষা করতে দেয়। এই পদ্ধতিটি UI লোডিং অবস্থা পরীক্ষণের জন্য দরকারী: fake 100 ms-এর জন্য বিরতি দেয়, এবং পরীক্ষণ যাচাই করে যে স্ক্রিনটি একটি লোডার দেখায়। Callback উৎপাদনে অনুপস্থিত — এটি সম্পূর্ণরূপে পরীক্ষণ কার্যকারিতা।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Fake-এ কার্যকরী যুক্তি থাকে — ফিল্টার করে, সাজায়, গণনা করে। Stub যুক্তি ছাড়াই কেবল পূর্বনির্ধারিত উত্তর ফেরত দেয়। যদি একটি অবজেক্টে শাখা (if/else, when) থাকে — এটি fake। যদি এটি শুধুমাত্র রিটার্ন মান ধারণ করে — এটি stub। Fake রক্ষণাবেক্ষণে বেশি ব্যয়বহুল কিন্তু আরও বাস্তবসম্মত পরীক্ষণ প্রদান করে।
যখন fake-এর যুক্তি উৎপাদনের যুক্তির সাথে মেলে না। উদাহরণস্বরূপ, FakeUserRepository কেস-সেনসিটিভ অনুসন্ধান ব্যবহার করে, যখন উৎপাদন সংস্করণ কেস-ইনসেনসিটিভ। পরীক্ষণ পাস করে, কিন্তু বাস্তবে একটি বাগ থাকে। সমাধান: fake-এর যুক্তি আলাদাভাবে পরীক্ষা করুন অথবা শুধুমাত্র সহজ যুক্তি (CRUD অপারেশন) সহ ইন্টারফেসের জন্য fakes ব্যবহার করুন। জটিল যুক্তির জন্য, বাস্তব ডেটাবেস সহ ইন্টিগ্রেশন পরীক্ষণ লিখুন।
ইন-মেমরি ডেটাবেস হল fake-এর একটি প্রকার। Room.inMemoryDatabaseBuilder() ইন-মেমরি SQLite তৈরি করে যা উৎপাদন ডেটাবেসের মতো আচরণ করে। এটি একটি পূর্ণাঙ্গ fake। কিন্তু fake রিপোজিটরি স্তরে (SQL ছাড়া) এবং নেটওয়ার্ক স্তরে (FakeApiService) হতে পারে। ইন-মেমরি ডেটাবেস হল fake-এর একটি বিশেষ ক্ষেত্রে যেখানে যুক্তি যতটা সম্ভব বাস্তবের কাছাকাছি।
হ্যাঁ, কিন্তু সতর্কতার সাথে। Fake রিপোজিটরির জন্য (ডেটা), Mock AnalyticsTracker-এর জন্য (ইভেন্ট যাচাই)। স্তর দ্বারা পৃথকীকরণ: ডেটা স্তরের জন্য fake, বিশ্লেষণ/লগিং স্তরের জন্য mock। একটি অবজেক্টকে একসাথে fake এবং mock করবেন না — এটি একক দায়িত্ব নীতি লঙ্ঘন করে এবং পরীক্ষণকে বিভ্রান্ত করে।
Fake পরীক্ষা করুন উৎপাদন বাস্তবায়নের মতো একই পরীক্ষণ দিয়ে। যদি আপনার UserRepositoryTest থাকে যা save, get, delete যাচাই করে — এটি দুবার চালান: FakeUserRepository এবং RealUserRepository দিয়ে। এটি নিশ্চিত করে যে fake উৎপাদন ক্লাসের আচরণ প্রতিলিপি করে। যদি fake ভিন্নভাবে আচরণ শুরু করে — পরীক্ষণ উভয় বাস্তবায়নেই ব্যর্থ হবে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন