স্ন্যাপশট টেস্টিং হল স্বয়ংক্রিয় ইউজার ইন্টারফেস যাচাইয়ের একটি পদ্ধতি যেখানে বর্তমান স্ক্রিন অবস্থার তুলনা পূর্ববর্তী টেস্ট রানে সংরক্ষিত রেফারেন্স ইমেজের (স্ন্যাপশট) সাথে করা হয়। যেকোনো ভিজ্যুয়াল অমিল একটি পরিবর্তন হিসেবে রেকর্ড করা হয় যার জন্য ডেভেলপারের নিশ্চিতকরণ প্রয়োজন। এলিমেন্টের উপস্থিতি পরীক্ষা করে এমন UI টেস্টের বিপরীতে, স্ন্যাপশট টেস্ট পিক্সেল-স্তরের পরিবর্তন — শিফট, রঙের বিচ্যুতি এবং লেআউট সমস্যা — সনাক্ত করে। Android Developers, 2024 অনুসারে, স্ন্যাপশট টেস্টিং ঐতিহ্যবাহী UI টেস্ট দ্বারা মিস হওয়া 30% পর্যন্ত ভিজ্যুয়াল রিগ্রেশন সনাক্ত করে, যা এটিকে একটি সামঞ্জস্যপূর্ণ ইন্টারফেস বজায় রাখার জন্য একটি অপরিহার্য টুল করে তোলে।
মূল পয়েন্ট
স্ন্যাপশট টেস্টিং একটি কৌশল যেখানে একটি টেস্ট UI কম্পোনেন্ট রেন্ডার করে, ফলস্বরূপ ইমেজটি রেফারেন্স হিসেবে সংরক্ষণ করে এবং পরবর্তী রানে বর্তমান রেন্ডারের সাথে এই রেফারেন্সের তুলনা করে। যদি ইমেজ মিলে যায় — টেস্ট পাস হয়। যদি পার্থক্য পাওয়া যায় — টেস্ট ফেল হয় এবং ডেভেলপার পরিবর্তিত পিক্সেল হাইলাইট করা একটি diff ইমেজ পান। কৌশলটি ওয়েব ডেভেলপমেন্ট (Jest স্ন্যাপশট) থেকে নেওয়া হয়েছে এবং মোবাইল প্ল্যাটফর্মের জন্য অভিযোজিত হয়েছে।
স্ন্যাপশট টেস্টের প্রধান মূল্য হল অপ্রত্যাশিত ভিজ্যুয়াল পরিবর্তনের স্বয়ংক্রিয় সনাক্তকরণ। একজন ডেভেলপার গ্লোবাল থিমে রঙের স্কিম পরিবর্তন করতে পারেন এবং দুর্ঘটনাক্রমে ডজনখানেক স্ক্রিনকে প্রভাবিত করতে পারেন। বাটন এবং টেক্সটের উপস্থিতি পরীক্ষা করে এমন UI টেস্ট এটি লক্ষ্য করবে না। একটি স্ন্যাপশট টেস্ট প্রতিটি প্রভাবিত স্ক্রিনের প্রতিটি পিক্সেল পরিবর্তন ক্যাপচার করবে, পরিবর্তনের প্রভাবের সম্পূর্ণ চিত্র প্রদান করবে।
Mobile DevOps Summit 2023 জরিপ অনুসারে, ক্লাসিক UI টেস্টের পাশাপাশি স্ন্যাপশট টেস্টিং ব্যবহারকারী দলগুলি রিলিজে ভিজ্যুয়াল ত্রুটির সংখ্যা 40% কমিয়ে দেয়। এই পদ্ধতি বিশেষ করে ডিজাইন সিস্টেম এবং কম্পোনেন্ট-ভিত্তিক আর্কিটেকচারযুক্ত প্রকল্পগুলিতে কার্যকর, যেখানে একটি বেস কম্পোনেন্ট পরিবর্তন করলে অ্যাপ্লিকেশনের ডজনখানেক স্ক্রিন প্রভাবিত হতে পারে।
মৌলিক পার্থক্য যাচাইয়ের বস্তুর মধ্যে রয়েছে। UI টেস্ট ইন্টারফেস এলিমেন্টের উপস্থিতি, অবস্থা এবং আচরণ পরীক্ষা করে: “বাটনটি দৃশ্যমান”, “টেক্সটে ত্রুটি বার্তা রয়েছে”, “চাপলে নতুন স্ক্রিন খোলে”। স্ন্যাপশট টেস্ট সম্পূর্ণ ভিজ্যুয়াল চেহারা পরীক্ষা করে: এলিমেন্টের অবস্থান, মার্জিন, রঙ, ফন্ট, ছায়া এবং গোলাকার কোণ। একটি স্ন্যাপশট টেস্ট প্রশ্নের উত্তর দেয় “স্ক্রিনটি কি প্রত্যাশিত দেখাচ্ছে?”, যেখানে একটি UI টেস্ট উত্তর দেয় “স্ক্রিনটি কি প্রত্যাশিতভাবে কাজ করছে?”
নির্বাহের গতিও ভিন্ন। UI টেস্ট এমুলেটর বা বাস্তব ডিভাইসে চলে, সম্পূর্ণ অ্যাপ্লিকেশন লোডিং প্রয়োজন, এবং প্রতি দৃশ্যে 10 সেকেন্ড থেকে এক মিনিট সময় নেয়। Paparazzi-এর মতো লাইব্রেরি ব্যবহার করে স্ন্যাপশট টেস্ট এমুলেটর চালানো ছাড়াই ভার্চুয়াল পরিবেশে কম্পোনেন্ট রেন্ডার করে, যা টেস্টের সময় 100–500 মিলিসেকেন্ডে কমিয়ে আনে। স্ন্যাপশট টেস্টের একটি সম্পূর্ণ সেট (50–100 স্ক্রিন) UI টেস্টের তুলনীয় সেটের জন্য 30–60 মিনিটের পরিবর্তে 2–5 মিনিটে নির্বাহিত হয়।
তবে, স্ন্যাপশট টেস্ট UI টেস্ট প্রতিস্থাপন করে না। সর্বোত্তম কৌশল একটি সংমিশ্রণ: স্ন্যাপশট টেস্ট ভিজ্যুয়াল রিগ্রেশন কভার করে (প্রাথমিক অবস্থায় প্রতিটি স্ক্রিনের রেন্ডার), যেখানে UI টেস্ট আচরণগত দিক (ক্লিক দৃশ্য, ইনপুট যাচাই, নেভিগেশন) কভার করে। এই সংমিশ্রণ ন্যূনতম CI রান সময়ের সাথে ইন্টারফেস সঠিকতায় 90% আত্মবিশ্বাস প্রদান করে।
অ্যান্ড্রয়েডে, প্রধান টুলস হল Paparazzi এবং Shot। Cash App-এর Paparazzi Layoutlib গ্র্যাভিটি লেআউট ব্যবহার করে এমুলেটর ছাড়াই JVM টেস্ট পরিবেশে কম্পোনেন্ট রেন্ডার করে। Karumi-এর Shot বাস্তব ডিভাইস বা এমুলেটরে ইনস্ট্রুমেন্টেশন স্ক্রিনশট নেয় এবং AShot লাইব্রেরির মাধ্যমে রেফারেন্সের সাথে তুলনা করে, রেজোলিউশন এবং পিক্সেল ঘনত্বের পার্থক্য বিবেচনায় নিয়ে।
Paparazzi এমুলেটর চালানোর প্রয়োজন নেই — Layoutlib-এর মাধ্যমে JVM-এ রেন্ডারিং করা হয়, যা ইউনিট টেস্টের সমান গতি প্রদান করে। লাইব্রেরি View সিস্টেম এবং Jetpack Compose উভয়ই সমর্থন করে। Compose-এর জন্য, paparazzi.snapshot { MyComposable() } মডিফায়ার ব্যবহার করুন। রেফারেন্স src/test/snapshots-এ সংরক্ষিত হয় এবং প্রতিটি রানে স্বয়ংক্রিয়ভাবে তুলনা করা হয়। সর্বোচ্চ পার্থক্য শতাংশ maxPercentDifference-এর মাধ্যমে কনফিগার করা হয়।
Point-Free-এর SnapshotTesting শুধু UIImage নয়, স্ট্রিং, JSON, Data এবং সম্পূর্ণ Core Data স্টোরের তুলনাও সমর্থন করে। এটি এটিকে শুধু UI স্ন্যাপশটের জন্যই নয়, JSON রেসপন্সের সিরিয়ালাইজেশন এবং ডিকোডিং যাচাইয়ের জন্যও একটি বহুমুখী টুল করে তোলে। SwiftUI-এর জন্য, .image(on: .iPhone13) মডিফায়ারসহ assertSnapshot এক্সটেনশন ব্যবহার করুন। record: true কৌশল প্রথম রানে রেফারেন্স তৈরি করে।
React Native-এর জন্য, জনপ্রিয় সমাধান হল jest-image-snapshot-এর সাথে react-native-testing-library সংমিশ্রণ। Node.js পরিবেশে কম্পোনেন্ট রেন্ডার করে এবং পরে ভার্চুয়াল DOM-এর JSON স্ন্যাপশট তুলনা করে স্ন্যাপশট টেস্টিংয়ের ওয়েব পদ্ধতি মোবাইল পরিবেশে স্থানান্তরিত হয়। এই পদ্ধতি নেটিভের চেয়ে দ্রুত কিন্তু কম নির্ভুল — এটি প্ল্যাটফর্ম-নির্দিষ্ট ফন্ট রেন্ডারিং এবং সিস্টেম কম্পোনেন্ট বৈশিষ্ট্য বিবেচনায় নেয় না। Flutter-এর জন্য, goldens টুলকিটের মাধ্যমে গোল্ডেন টেস্টিং ব্যবহার করা হয়।
আসুন অ্যান্ড্রয়েড (Paparazzi) এবং iOS (SnapshotTesting)-এর জন্য স্ন্যাপশট টেস্ট দেখি। উভয় উদাহরণ একটি কম্পোনেন্টের চেহারা পরীক্ষা করে — অ্যাভাটার, নাম এবং অবস্থাসহ একটি ইউজার কার্ড। টেস্ট কম্পোনেন্টটি রেন্ডার করে টেস্ট ডেটা সহ এবং রিপোজিটরিতে সংরক্ষিত রেফারেন্স ইমেজের সাথে ফলাফল তুলনা করে।
Paparazzi রেন্ডার ক্যাপচার করতে @Test অ্যানোটেশন এবং snapshot() মেথড ব্যবহার করে। রেফারেন্স src/test/snapshots ফোল্ডারে সংরক্ষিত হয় এবং তুলনার জন্য পরবর্তী রানে স্বয়ংক্রিয়ভাবে লোড হয়।
class UserCardSnapshotTest {
@get:Rule
val paparazzi = Paparazzi(
theme = "Theme.MyApp",
maxPercentDifference = 0.1
)
@Test
fun userCard_defaultState() {
val card = UserCard(
name = "Alice Johnson",
status = "Online",
avatarUrl = "https://example.com/avatar.png"
)
paparazzi.snapshot(card)
}
@Test
fun userCard_offlineState() {
val card = UserCard(
name = "Bob Smith",
status = "Offline",
avatarUrl = null
)
paparazzi.snapshot(card, name = "user_card_offline")
}
}
SnapshotTesting assertSnapshot-এর ভিতরে .snapshot() মডিফায়ার ব্যবহার করে। লাইব্রেরি স্বয়ংক্রিয়ভাবে ফরম্যাট নির্ধারণ করে — UIView-এর জন্য UIImage, টেক্সটের জন্য String, বাইনারি ডেটার জন্য Data।
import SnapshotTesting
import XCTest
class UserCardSnapshotTests: XCTestCase {
func testUserCardDefaultState() {
let card = UserCardView(
name: "Alice Johnson",
status: "Online",
avatarURL: URL(string: "https://example.com/avatar.png")
)
let controller = UIHostingController(rootView: card)
assertSnapshot(matching: controller, as: .image(on: .iPhone13))
}
func testUserCardOfflineState() {
let card = UserCardView(
name: "Bob Smith",
status: "Offline",
avatarURL: nil
)
assertSnapshot(matching: card, as: .image(on: .iPhone13))
}
}
একটি সাধারণ ওয়ার্কফ্লো চারটি ধাপ অন্তর্ভুক্ত করে। প্রথম রান (রেকর্ড মোড): সমস্ত স্ন্যাপশট টেস্ট রেকর্ড মোডে নির্বাহিত হয় — রেফারেন্স ইমেজ তৈরি করা হয় এবং রিপোজিটরিতে সংরক্ষণ করা হয়। এই ধাপটি প্রাথমিক টেস্ট সেটআপের সময় বা ইন্টারফেসে সচেতন পরিবর্তনের পরে সঞ্চালিত হয়। রেকর্ডিংয়ের পরে, রেফারেন্স কোডের সাথে কমিট করা হয় — তারা প্রকল্পের অংশ হয়ে যায়।
পরবর্তী রানে, টেস্টগুলি তুলনা মোডে কাজ করে: প্রতিটি নতুন রেন্ডার রেফারেন্সের সাথে তুলনা করা হয়। যদি পার্থক্য পাওয়া যায়, একটি diff ইমেজ তৈরি হয়: রেফারেন্সের সাথে মেলে এমন পিক্সেল সবুজে হাইলাইট হয়, ভিন্ন পিক্সেল লালে। ডেভেলপার diff অধ্যয়ন করে এবং সিদ্ধান্ত নেয়: যদি পরিবর্তনটি প্রত্যাশিত হয় (সচেতন ডিজাইন পরিবর্তন), রেফারেন্স record কমান্ড দিয়ে আপডেট করা হয়; যদি অপ্রত্যাশিত হয় — বাগ ঠিক করা হয়। রেফারেন্স আপডেট একটি একক কমান্ড দিয়ে করা হয়: Paparazzi-এর জন্য এটি `./gradlew recordPaparazzi`, SnapshotTesting-এর জন্য — `assertSnapshot(record: true)`।
Spotify Engineering Blog (2022) অনুসারে, বর্ণিত ওয়ার্কফ্লো ব্যবহারকারী দলগুলি diff ইমেজ বিশ্লেষণে প্রতি টেস্টে গড়ে 2 মিনিট ব্যয় করে। 50টি স্ন্যাপশট টেস্টের একটি সেটের সাথে, একটি সম্পূর্ণ রেফারেন্স আপডেট চক্র 15–20 মিনিট সময় নেয়, যা 50 স্ক্রিনে ভিজ্যুয়াল পরিবর্তনের ম্যানুয়াল যাচাইয়ের তুলনায় উল্লেখযোগ্যভাবে দ্রুত।
স্ন্যাপশট টেস্টের মৌলিক সীমাবদ্ধতা রয়েছে। পরিবেশ সংবেদনশীলতা: একই কম্পোনেন্ট বিভিন্ন OS সংস্করণ, স্ক্রিন ঘনত্ব এবং ফন্ট কনফিগারেশনে ভিন্নভাবে রেন্ডার হতে পারে। এক মেশিনে তৈরি রেফারেন্স CI সার্ভারে রেন্ডার থেকে ভিন্ন হতে পারে। সমাধান হল নির্দিষ্ট পরিবেশ প্যারামিটার ব্যবহার করা: Paparazzi-এর জন্য একটি নির্দিষ্ট Layoutlib সংস্করণ বা SnapshotTesting-এর জন্য সঠিক ডিভাইস মডেল।
অ্যান্টি-প্যাটার্ন #1: দৈত্যাকার স্ন্যাপশট — একটি স্ন্যাপশট টেস্ট যা পুরো স্ক্রিন ক্যাপচার করে, যেকোনো কম্পোনেন্টের প্রতিটি সামান্য পরিবর্তনে ফেল হয়। সঠিক পদ্ধতি হল পৃথক কম্পোনেন্ট (বাটন, কার্ড, ইনপুট ফিল্ড) আলাদাভাবে পরীক্ষা করা। প্রতিটি কম্পোনেন্ট স্বাধীনভাবে পরীক্ষিত হয়, যা পরিবর্তনের উৎসের সঠিক সনাক্তকরণ প্রদান করে। অ্যান্টি-প্যাটার্ন #2: diff উপেক্ষা করা — diff ইমেজ বিশ্লেষণ না করে স্বয়ংক্রিয়ভাবে রেফারেন্স আপডেট করা স্ন্যাপশট টেস্টের মান শূন্যে নামিয়ে আনে। প্রতিটি diff-এর জন্য ডেভেলপারের সচেতন সিদ্ধান্ত প্রয়োজন।
Better Engineering Blog (2023) অনুসারে, স্ন্যাপশট টেস্ট সর্বাধিক সুবিধা দেয় যখন ডিজাইন সিস্টেম কম্পোনেন্ট এবং মূল স্ক্রিনগুলি প্রাথমিক অবস্থায় — খালি, পূর্ণ, ত্রুটি এবং সীমা — কভার করে। রেন্ডারিংয়ে টাইমস্ট্যাম্পের নন-ডিটারমিনিস্টিক প্রকৃতির কারণে স্ন্যাপশট টেস্টের মাধ্যমে অ্যানিমেশন এবং ডায়নামিক অবস্থা কভার করা অদক্ষ — এই ধরনের দৃশ্যের জন্য ভিডিও রেকর্ডিং বা ম্যানুয়াল QA পরীক্ষা বেশি উপযুক্ত।
সচরাচর জিজ্ঞাসিত প্রশ্ন
না, স্ন্যাপশট টেস্ট ভিজ্যুয়াল চেহারা পরীক্ষা করে, যেখানে UI টেস্ট ইন্টারফেস আচরণ পরীক্ষা করে। সর্বোত্তম কৌশল হল উভয় পদ্ধতি একত্রিত করা: ভিজ্যুয়াল রিগ্রেশনের জন্য স্ন্যাপশট, দৃশ্য এবং নেভিগেশনের জন্য UI টেস্ট। স্ন্যাপশট উত্তর দেয় “এটি কি সঠিক দেখাচ্ছে”, UI টেস্ট উত্তর দেয় “এটি কি সঠিক কাজ করছে”।
প্রতিটি সচেতন ডিজাইন পরিবর্তনের সাথে রেফারেন্স আপডেট করা হয়: একটি নতুন থিম রঙ, পরিবর্তিত মার্জিন, এলিমেন্ট যোগ বা অপসারণ। আপডেট রেকর্ড মোডের মাধ্যমে করা হয়, তারপরে diff ইমেজ কোড রিভিউতে পর্যালোচনা করা হয় যাতে নিশ্চিত করা যায় যে পরিবর্তনগুলি ডিজাইনারের প্রত্যাশার সাথে মেলে।
প্রথম এবং সর্বাগ্রে, ডিজাইন সিস্টেম কম্পোনেন্ট — বাটন, কার্ড, ইনপুট ফিল্ড, মোডাল উইন্ডো। তারপরে প্রাথমিক অবস্থায় মূল স্ক্রিন। স্ন্যাপশট দিয়ে পরীক্ষা করবেন না অ্যানিমেশন, WebView, মানচিত্র এবং ডায়নামিক কন্টেন্টযুক্ত স্ক্রিন — নন-ডিটারমিনিজমের কারণে স্ন্যাপশট মিথ্যা ব্যর্থতা দেয়।
রেকর্ড এবং টেস্ট মোড উভয়ের জন্য একই API Level ব্যবহার করুন। Paparazzi-এর জন্য, কনফিগারেশনে একটি নির্দিষ্ট Layoutlib সংস্করণ নির্দিষ্ট করুন। SnapshotTesting-এর জন্য, ডিভাইস মডেল স্থির করুন। Android 14-এ তৈরি রেফারেন্স সিস্টেম ফন্ট এবং Material থিমের পরিবর্তনের কারণে Android 12-এর রেন্ডার থেকে ভিন্ন হতে পারে।
CI-তে, স্ন্যাপশট টেস্ট ভেরিফাই মোডে চলে। যদি একটি টেস্ট ফেল হয়, CI বিল্ড আর্টিফ্যাক্টে diff ইমেজ দেখায়। রেকর্ড মোড (রেফারেন্স আপডেট) ডেভেলপার দ্বারা স্থানীয়ভাবে বা ম্যানুয়াল ট্রিগারসহ একটি পৃথক CI টাস্কে সম্পাদিত হয়। রেফারেন্স ইমেজ রিপোজিটরিতে কমিট করা আবশ্যক।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন