Espresso হল Android অ্যাপ্লিকেশনের স্বয়ংক্রিয় UI পরীক্ষার জন্য একটি ফ্রেমওয়ার্ক, যা Google টিম দ্বারা তৈরি এবং AndroidX Test-এর অংশ। ইন্সট্রুমেন্টেড টেস্টের বিপরীতে যা বিচ্ছিন্ন উপাদান পরীক্ষা করে, Espresso প্রকৃত UI-এর সাথে ইন্টারঅ্যাক্ট করে: বাটন চাপে, টেক্সট ইনপুট করে, উপাদানের দৃশ্যমানতা পরীক্ষা করে। Google Android Developers-এর মতে, Espresso UI থ্রেডের সাথে স্বয়ংক্রিয় সিঙ্ক্রোনাইজেশন প্রদান করে, যা ম্যানুয়াল Thread.sleep()-এর প্রয়োজনীয়তা দূর করে।
মূল বিষয়
Espresso হল Android-এর জন্য স্বয়ংক্রিয় UI পরীক্ষা লেখার একটি লাইব্রেরি, যা Google AndroidX Test-এর অংশ। এটি স্ক্রিনে View উপাদান খোঁজার, সেগুলিতে ক্রিয়া সম্পাদনের (ক্লিক, ইনপুট, সোয়াইপ) এবং তাদের অবস্থা পরীক্ষা করার (প্রদর্শিত, টেক্সট আছে, সক্রিয়) জন্য API প্রদান করে।
Espresso-র মূল বৈশিষ্ট্য হল অ্যাপ্লিকেশনের মূল থ্রেডের সাথে স্বয়ংক্রিয় সিঙ্ক্রোনাইজেশন। ফ্রেমওয়ার্ক পরবর্তী পরীক্ষা কার্যকর করার আগে সমস্ত অ্যাসিঙ্ক্রোনাস কাজ (coroutines, AsyncTask, Handler) শেষ হওয়ার জন্য অপেক্ষা করে। এটি রেস কন্ডিশনের কারণে সৃষ্ট অস্থির পরীক্ষা দূর করে এবং UI পরীক্ষাগুলিকে স্থিতিশীল ও নির্ভরযোগ্য করে তোলে — কোনো পরীক্ষায় Thread.sleep() বা অপেক্ষা লুপ থাকে না।
Espresso তিন-পাওয়ালা কুকুর নীতি অনুসরণ করে — একটি পরীক্ষা তিনটি ধাপ নিয়ে গঠিত: উপাদান খুঁজুন (ViewMatcher), ক্রিয়া সম্পাদন করুন (ViewAction), ফলাফল পরীক্ষা করুন (ViewAssertion)। তিনটি ধাপই কলের একটি চেইনে লেখা হয়: onView().perform().check()। এই ধারণা পরীক্ষাগুলিকে পূর্বাভাসযোগ্য এবং পড়তে সহজ করে তোলে — প্রতিটি পরীক্ষা স্পষ্টভাবে বর্ণনা করে কী খোঁজে, কী করে এবং কী পরীক্ষা করে।
আর্কিটেকচার Espresso তিনটি উপাদানের উপর ভিত্তি করে: Espresso (প্রবেশ বিন্দু — স্ট্যাটিক পদ্ধতি onView এবং onData), ViewMatchers (উপাদান অনুসন্ধান), ViewActions (ক্রিয়া) এবং ViewAssertions (পরীক্ষা)। অভ্যন্তরীণভাবে, ফ্রেমওয়ার্ক UI থ্রেডের সাথে সিঙ্ক্রোনাইজেশনের জন্য Idling Resource ব্যবহার করে।
সবচেয়ে সহজ পরীক্ষা ID দ্বারা একটি বাটন খুঁজে পায়, ক্লিক করে এবং পরীক্ষা করে যে “শেষ” টেক্সটটি দেখা যাচ্ছে। পরীক্ষার দৃষ্টিকোণ থেকে সমস্ত অপারেশন সিঙ্ক্রোনাস — Espresso গ্যারান্টি দেয় যে UI থ্রেড পরীক্ষা চালিয়ে যাওয়ার আগে ইভেন্ট প্রক্রিয়াকরণ শেষ করেছে। এটি একটি অন্তর্নির্মিত অপেক্ষা পদ্ধতির মাধ্যমে অর্জন করা হয়: onView UI নিষ্ক্রিয় না হওয়া পর্যন্ত পরীক্ষা কার্যকর করা ব্লক করে।
@Test
fun buttonClick_showsSuccessText() {
// ID দ্বারা বাটন খুঁজুন এবং ক্লিক করুন
onView(withId(R.id.button_submit))
.perform(click())
// পরীক্ষা করুন যে “শেষ” টেক্সট প্রদর্শিত হচ্ছে
onView(withText("শেষ"))
.check(matches(isDisplayed()))
}
Espresso পরীক্ষা শুরু করতে, ActivityScenario (AndroidX Test) ব্যবহার করা হয়, যা একটি নির্দিষ্ট অবস্থায় Activity তৈরি করে — চলমান, বিরাম দেওয়া, বা ধ্বংস করা। ActivityScenario বিশুদ্ধ UI পরীক্ষার পাশাপাশি Activity জীবনচক্র পরীক্ষা করার অনুমতি দেয়। উদাহরণস্বরূপ, আপনি পরীক্ষা করতে পারেন যে স্ক্রিন ঘোরানোর সময় (Activity পুনঃনির্মাণ) ডেটা সংরক্ষিত থাকে এবং ধ্বংসের পরে পুনরুদ্ধার করা হয়।
ViewMatchers হল Espresso.onView ক্লাসের পদ্ধতির একটি সেট যা বিভিন্ন মানদণ্ড দ্বারা স্ক্রিনে Views খুঁজে পাওয়ার অনুমতি দেয়: রিসোর্স ID (R.id), টেক্সট, হিন্ট, প্যারেন্ট উপাদান এবং হায়ারার্কি। যদি একটি ম্যাচার অনন্য ফলাফল না দেয়, তাহলে ম্যাচারগুলি allOf() ব্যবহার করে একত্রিত করা যেতে পারে।
| ম্যাচার | উদ্দেশ্য |
|---|---|
| withId(R.id.name) | রিসোর্স ID দ্বারা অনুসন্ধান |
| withText(“টেক্সট”) | প্রদর্শিত টেক্সট দ্বারা অনুসন্ধান |
| withHint(“সংকেত”) | EditText-এর হিন্ট অ্যাট্রিবিউট দ্বারা অনুসন্ধান |
| isDisplayed() | পরীক্ষা করে যে উপাদানটি স্ক্রিনে দৃশ্যমান |
| hasSibling(matcher) | সহোদর উপাদান দ্বারা অনুসন্ধান |
| allOf(m1, m2) | একাধিক ম্যাচারের সংমিশ্রণ |
যদি স্ক্রিনে একাধিক অভিন্ন উপাদান থাকে (যেমন, ভিন্ন টেক্সট সহ দুটি TextView), তাহলে allOf ব্যবহার করে ম্যাচার একত্রিত করা সুবিধাজনক: onView(allOf(withId(R.id.title), withText(“হ্যালো”)))। এটি একক উপাদান নির্বাচন নিশ্চিত করে। বিপরীত অপারেটর — not() — উপাদানগুলিকে অনুসন্ধান থেকে বাদ দেয়, এবং hasSibling() পরিচিত উপাদানের পাশে উপাদান খুঁজে পায়।
ViewActions হল ক্রিয়া যা Espresso প্রাপ্ত View-এর উপর সম্পাদন করে: click(), typeText(), clearText(), scrollTo(), swipeLeft() এবং অন্যান্য। ক্রিয়াগুলি perform() পদ্ধতিতে পাস করা হয়, যা একসাথে একাধিক ক্রিয়া গ্রহণ করতে পারে।
perform() পদ্ধতি vararg ViewAction গ্রহণ করে, যা একটি উপাদানের উপর ক্রিয়ার ক্রম কার্যকর করার অনুমতি দেয়: ফিল্ড পরিষ্কার করুন, নতুন টেক্সট লিখুন, কীবোর্ড বন্ধ করুন এবং বাটন চাপুন। সমস্ত ক্রিয়া তালিকাভুক্ত ক্রমে কার্যকর হয়, এবং Espresso গ্যারান্টি দেয় যে পরবর্তী ক্রিয়া শুরু হওয়ার আগে পূর্ববর্তী ক্রিয়া সম্পূর্ণ হয়েছে।
// EditText-এ টেক্সট লিখুন এবং বাটন চাপুন
onView(withId(R.id.edit_email))
.perform(
clearText(),
typeText("user@example.com"),
closeSoftKeyboard()
)
onView(withId(R.id.button_login))
.perform(click())
AdapterView (ListView, RecyclerView)-এর ভিতরে উপাদানের জন্য, onView-এর পরিবর্তে onData() পদ্ধতি ব্যবহার করা হয়। এটি Views-এর পরিবর্তে অ্যাডাপ্টার ডেটার সাথে কাজ করে — মডেল বিষয়বস্তু দ্বারা উপাদান খুঁজে পায় এবং আরও ক্রিয়ার জন্য সংশ্লিষ্ট View ফেরত দেয়। onData মডেল ডেটা ফিল্ড দ্বারা উপাদান সনাক্ত করতে hamcrest ম্যাচার ব্যবহার করে।
ViewAssertions পরীক্ষা করে যে View একটি নির্দিষ্ট অবস্থায় আছে। মৌলিক পদ্ধতি — matches(matcher) — পরীক্ষা করে যে উপাদানটি প্রদত্ত ম্যাচারের সাথে মেলে। অতিরিক্তভাবে, Espresso doesNotExist() (উপাদান অনুপস্থিত) এবং selectedDescendantsMatch() (নেস্টেড উপাদান পরীক্ষা) অফার করে।
UI পরীক্ষায় সবচেয়ে ঘন ঘন পরীক্ষা: উপাদান প্রদর্শিত হচ্ছে (isDisplayed), উপাদানে নির্দিষ্ট টেক্সট আছে (withText), উপাদান সক্রিয় (isEnabled), উপাদান নির্বাচিত নয় (isNotChecked)। প্রতিটি পরীক্ষা ব্যর্থ হলে বিস্তারিত ব্যতিক্রম ছুঁড়ে — স্ক্রিনে View হায়ারার্কি সহ। এটি ডিবাগিং সহজ করে: ত্রুটি বার্তা দেখায় যে পরীক্ষার সময় স্ক্রিনে আসলে কী কী উপাদান ছিল।
যদি মানক পরীক্ষা অপর্যাপ্ত হয়, তাহলে ViewAssertion ইন্টারফেসের মাধ্যমে কাস্টম পরীক্ষা তৈরি করা যেতে পারে। একটি কাস্টম অ্যাসারশন একটি View গ্রহণ করে এবং প্রোগ্রামেটিকভাবে তার অবস্থা পরীক্ষা করতে পারে — উদাহরণস্বরূপ, টেক্সটের রং, প্যাডিং, বা কাস্টম উপাদানের অবস্থা যা মানক ম্যাচারের মাধ্যমে উন্মুক্ত নয়।
// পরীক্ষা: TextView প্রদর্শিত হচ্ছে এবং টেক্সট আছে
onView(withId(R.id.text_welcome))
.check(matches(isDisplayed()))
.check(matches(withText("স্বাগতম")))
// পরীক্ষা: উপাদান প্রদর্শিত হচ্ছে না
onView(withId(R.id.progress_bar))
.check(doesNotExist())
Idling Resource হল অ্যাসিঙ্ক্রোনাস অপারেশনের সাথে পরীক্ষা সিঙ্ক্রোনাইজ করার Espresso-র পদ্ধতি। ডিফল্টরূপে, Espresso Handler, AsyncTask এবং coroutines (coroutinesIdlingResource-এর মাধ্যমে) অপেক্ষা করে। যদি অ্যাপ্লিকেশন কাস্টম থ্রেড বা কলব্যাক পরিষেবার মাধ্যমে পটভূমি কাজ করে, তাহলে কাস্টম Idling Resource নিবন্ধন করা প্রয়োজন।
AndroidX Test 1.4.0 থেকে শুরু করে, Espresso CoroutinesIdlingResource-এর মাধ্যমে coroutines সমর্থন করে। পরীক্ষা UI পরীক্ষা করার আগে স্বয়ংক্রিয়ভাবে সমস্ত চালু করা coroutines সম্পূর্ণ হওয়ার জন্য অপেক্ষা করে। আরও জটিল পরিস্থিতির জন্য, CountingIdlingResource ব্যবহার করা হয় — একটি কাউন্টার যা কাজ শুরু হলে বৃদ্ধি পায় এবং সম্পূর্ণ হলে হ্রাস পায়।
// OkHttp-এর জন্য IdlingResource নিবন্ধন করুন
class OkHttpIdlingResource(
private val client: OkHttpClient
) : IdlingResource {
private var isIdle = true
private var watcher: IdlingResource.ResourceCallback? = null
override fun getName() = "OkHttp"
override fun isIdleNow() = isIdle
override fun registerIdleTransitionCallback(
callback: IdlingResource.ResourceCallback
) {
watcher = callback
}
}
সংযোগ Android প্রকল্পে Espresso মডিউল স্তরের build.gradle-এ নির্ভরতা যোগ করে করা হয়। Espresso AndroidX Test-এর অংশ, তাই Espresso core, এক্সটেনশন এবং JUnit ইন্টিগ্রেশনের জন্য নির্ভরতা উল্লেখ করাই যথেষ্ট। পরীক্ষাগুলি src/androidTest ডিরেক্টরিতে রাখা হয় এবং AndroidJUnitRunner-এর মাধ্যমে ফিজিক্যাল ডিভাইস বা এমুলেটরে চালানো হয়।
ন্যূনতম নির্ভরতা সেটে espresso-core (core), espresso-contrib (RecyclerView, Drawer, Picker-এর জন্য অতিরিক্ত ম্যাচার) এবং runner (AndroidX টেস্ট রানার) অন্তর্ভুক্ত। সমস্ত পরীক্ষা Android Test Orchestrator-এর মাধ্যমে এমুলেটর বা ফিজিক্যাল ডিভাইসে চালানো হয়।
// build.gradle.kts (androidTest নির্ভরতা)
android {
defaultConfig {
testInstrumentationRunner =
"androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test.espresso:espresso-contrib:3.6.1")
androidTestImplementation("androidx.test:runner:1.6.1")
androidTestImplementation("androidx.test:rules:1.6.1")
}
Espresso পরীক্ষাগুলি Google Android Test Orchestrator-এর মাধ্যমে চালানো যেতে পারে, যা প্রতিটি পরীক্ষাকে আলাদা প্রক্রিয়ায় বিচ্ছিন্ন করে এবং চলার মধ্যে অবস্থা পরিষ্কার করে। এটি পূর্ববর্তী পরীক্ষার অবশিষ্ট ডেটার কারণে সৃষ্ট অস্থির পরীক্ষা দূর করে এবং CI সার্ভারে স্থিতিশীলতা বাড়ায়। সমান্তরাল কার্যকর করার জন্য, sharding ব্যবহার করা হয় — একাধিক এমুলেটরের মধ্যে পরীক্ষা বিতরণ করা।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Espresso অ্যাপ্লিকেশন প্রক্রিয়ার ভিতরে কাজ করে এবং UI থ্রেডের সাথে স্বয়ংক্রিয় সিঙ্ক্রোনাইজেশন ব্যবহার করে। UI Automator সিস্টেম স্তরে কাজ করে, অন্যান্য অ্যাপ্লিকেশনের সাথে ইন্টারঅ্যাক্ট করতে পারে, কিন্তু ম্যানুয়াল অপেক্ষা ব্যবস্থাপনা প্রয়োজন।
এটি Google উপস্থাপনা থেকে একটি রূপক: Espresso পরীক্ষা তিনটি স্তম্ভের উপর দাঁড়িয়ে থাকে — ViewMatcher (অনুসন্ধান), ViewAction (ক্রিয়া) এবং ViewAssertion (পরীক্ষা)। যেকোনো একটি সরিয়ে ফেললে পরীক্ষা অস্থির হয়ে যায়, তিন-পাওয়ালা কুকুরের মতো।
RecyclerView-এর জন্য espresso-contrib লাইব্রেরি এবং onView(withId(R.id.recycler)).perform(actionOnItemAtPosition(0, click()))-এর মতো পদ্ধতি ব্যবহার করা হয়। বিকল্প হল AdapterView-এর জন্য onData() বা RecyclerView-এর ভিতরে টেক্সট দ্বারা উপাদান খোঁজার জন্য কাস্টম ViewAction। অতিরিক্তভাবে, espresso-contrib থেকে RecyclerViewActions ব্যবহার করে উপাদানে স্ক্রোল করা এবং তার উপর ক্রিয়া করা যেতে পারে।
ফ্ল্যাকি টেস্ট — একটি পরীক্ষা যা কোড পরিবর্তন ছাড়াই মাঝে মাঝে ব্যর্থ হয়, রেস কন্ডিশন বা অ্যাসিঙ্ক্রোনাসিটির কারণে। Espresso এই সমস্যা Idling Resource-এর মাধ্যমে সমাধান করে — পরীক্ষা করার আগে সমস্ত পটভূমি কাজ সম্পূর্ণ হওয়ার জন্য অপেক্ষা করা।
Espresso নিজে স্ক্রিনশট পরীক্ষার জন্য ডিজাইন করা নয়, তবে এটি Shot বা Paparazzi-এর মতো লাইব্রেরির সাথে একত্রিত করা যেতে পারে। Espresso UIকে কাঙ্ক্ষিত অবস্থায় প্রস্তুত করে, এবং তুলনা লাইব্রেরি একটি স্ক্রিনশট নেয় এবং রেফারেন্সের সাথে তুলনা করে। এই পদ্ধতিকে ভিজুয়াল রিগ্রেশন টেস্টিং বলা হয় এবং এটি ইন্টারফেসে অপ্রত্যাশিত পরিবর্তন খুঁজে পেতে সহায়তা করে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন