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)، ٹیکسٹ، اشارہ، والدین کا عنصر اور درجہ بندی۔ اگر ایک matcher منفرد نتیجہ نہیں دیتا، تو matchers کو 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 matchers استعمال کرتا ہے۔
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 کور، ایکسٹینشنز اور JUnit انٹیگریشن کے لیے انحصار بتانا کافی ہے۔ ٹیسٹ src/androidTest ڈائریکٹری میں رکھے جاتے ہیں اور AndroidJUnitRunner کے ذریعے فزیکل ڈیوائس یا ایمولیٹر پر چلائے جاتے ہیں۔
کم از کم انحصار سیٹ میں espresso-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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں