स्नैपशॉट परीक्षण स्वचालित उपयोगकर्ता इंटरफ़ेस सत्यापन की एक विधि है जिसमें वर्तमान स्क्रीन स्थिति की तुलना पिछले परीक्षण रन में सहेजी गई संदर्भ छवि (स्नैपशॉट) से की जाती है। किसी भी दृश्य विसंगति को डेवलपर की पुष्टि की आवश्यकता वाले परिवर्तन के रूप में दर्ज किया जाता है। UI परीक्षणों के विपरीत जो तत्वों की उपस्थिति की जाँच करते हैं, स्नैपशॉट परीक्षण पिक्सेल-स्तर के परिवर्तनों — शिफ्ट, रंग विचलन और लेआउट समस्याओं — को पकड़ते हैं। Android Developers, 2024 के अनुसार, स्नैपशॉट परीक्षण पारंपरिक UI परीक्षणों द्वारा छोड़े गए 30% तक दृश्य रिग्रेशन का पता लगाता है, जो इसे एक सुसंगत इंटरफ़ेस बनाए रखने के लिए एक अपरिहार्य उपकरण बनाता है।
मुख्य बिंदु
स्नैपशॉट परीक्षण (snapshot testing) एक तकनीक है जिसमें एक परीक्षण 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 के लिए, react-native-testing-library को jest-image-snapshot के साथ संयोजित करना लोकप्रिय समाधान है। स्नैपशॉट परीक्षण के लिए वेब दृष्टिकोण को Node.js वातावरण में घटकों को रेंडर करके और बाद में वर्चुअल DOM के JSON स्नैपशॉट की तुलना करके मोबाइल वातावरण में स्थानांतरित किया जाता है। यह दृष्टिकोण देशी से तेज़ है लेकिन कम सटीक — यह प्लेटफ़ॉर्म-विशिष्ट फ़ॉन्ट रेंडरिंग और सिस्टम घटक सुविधाओं को ध्यान में नहीं रखता है। Flutter के लिए, goldens toolkit के माध्यम से golden परीक्षण का उपयोग किया जाता है।
आइए एंड्रॉइड (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 में, स्नैपशॉट परीक्षण सत्यापन मोड (verify) में चलते हैं। यदि कोई परीक्षण विफल होता है, CI बिल्ड आर्टिफैक्ट में diff छवि दिखाता है। रिकॉर्ड मोड (संदर्भ अद्यतन) डेवलपर द्वारा स्थानीय रूप से या मैन्युअल ट्रिगर के साथ एक अलग CI कार्य में किया जाता है। संदर्भ छवियों को रिपॉजिटरी में कमिट किया जाना चाहिए।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें