UI অটোমেটর দিয়ে স্বয়ংক্রিয় পরীক্ষা লিখুন

UI অটোমেটর টেস্টিং ফ্রেমওয়ার্ক ব্যবহারকারীর অ্যাপ এবং সিস্টেম অ্যাপের সাথে ইন্টারঅ্যাক্ট করে এমন UI পরীক্ষা তৈরি করতে API-এর একটি সেট প্রদান করে।

আধুনিক UI অটোমেটর পরীক্ষার ভূমিকা

UI অটোমেটর 2.4 একটি সুবিন্যস্ত, কোটলিন-বান্ধব ডোমেন স্পেসিফিক ল্যাঙ্গুয়েজ (DSL) প্রবর্তন করে যা Android এর জন্য UI পরীক্ষা লেখাকে সহজ করে। এই নতুন এপিআই সারফেস প্রিডিকেট-ভিত্তিক এলিমেন্ট ফাইন্ডিং এবং অ্যাপ স্টেটের উপর সুস্পষ্ট নিয়ন্ত্রণের উপর ফোকাস করে। আরও রক্ষণাবেক্ষণযোগ্য এবং নির্ভরযোগ্য স্বয়ংক্রিয় পরীক্ষা তৈরি করতে এটি ব্যবহার করুন।

UI অটোমেটর আপনাকে অ্যাপের প্রক্রিয়ার বাইরে থেকে একটি অ্যাপ পরীক্ষা করতে দেয়। এটি আপনাকে মিনিফিকেশন প্রয়োগ করে রিলিজ সংস্করণ পরীক্ষা করতে দেয়। ম্যাক্রোবেঞ্চমার্ক পরীক্ষা লেখার সময় UI অটোমেটরও সাহায্য করে।

আধুনিক পদ্ধতির মূল বৈশিষ্ট্যগুলির মধ্যে রয়েছে:

  • ক্লিনার এবং আরও অভিব্যক্তিপূর্ণ পরীক্ষার কোডের জন্য একটি উত্সর্গীকৃত uiAutomator পরীক্ষার সুযোগ।
  • স্পষ্ট ভবিষ্যদ্বাণী সহ UI উপাদানগুলি সন্ধানের জন্য onElement , onElements , এবং onElementOrNull এর মতো পদ্ধতি৷
  • কন্ডিশনাল এলিমেন্ট onElement*(timeoutMs: Long = 10000)
  • সুস্পষ্ট অ্যাপ স্টেট ম্যানেজমেন্ট যেমন waitForStable এবং waitForAppToBeVisible
  • মাল্টি-উইন্ডো টেস্টিং পরিস্থিতির জন্য অ্যাক্সেসিবিলিটি উইন্ডো নোডের সাথে সরাসরি মিথস্ক্রিয়া।
  • ভিজ্যুয়াল টেস্টিং এবং ডিবাগিংয়ের জন্য অন্তর্নির্মিত স্ক্রিনশট ক্ষমতা এবং একটি ResultsReporter

আপনার প্রকল্প সেট আপ করুন

আধুনিক UI অটোমেটর API ব্যবহার শুরু করতে, সর্বশেষ নির্ভরতা অন্তর্ভুক্ত করতে আপনার প্রকল্পের build.gradle.kts ফাইল আপডেট করুন:

কোটলিন

dependencies {
  ...
  androidTestImplementation("androidx.test.uiautomator:uiautomator:2.4.0-alpha05")
}

গ্রোভি

dependencies {
  ...
  androidTestImplementation "androidx.test.uiautomator:uiautomator:2.4.0-alpha05"
}

মূল API ধারণা

নিম্নলিখিত বিভাগগুলি আধুনিক UI অটোমেটর API-এর মূল ধারণাগুলি বর্ণনা করে৷

uiAutomator পরীক্ষার সুযোগ

uiAutomator { ... } ব্লকের মধ্যে সমস্ত নতুন UI অটোমেটর API অ্যাক্সেস করুন৷ এই ফাংশনটি একটি UiAutomatorTestScope তৈরি করে যা আপনার পরীক্ষার অপারেশনের জন্য একটি সংক্ষিপ্ত এবং টাইপ-নিরাপদ পরিবেশ প্রদান করে।

uiAutomator {
  // All your UI Automator actions go here
  startApp("com.example.targetapp")
  onElement { textAsString() == "Hello, World!" }.click()
}

UI উপাদান খুঁজুন

UI উপাদানগুলি সনাক্ত করতে পূর্বাভাস সহ UI অটোমেটর API ব্যবহার করুন৷ এই পূর্বাভাসগুলি আপনাকে টেক্সট, নির্বাচিত বা ফোকাসড স্টেট এবং বিষয়বস্তুর বিবরণের মতো বৈশিষ্ট্যগুলির জন্য শর্তগুলি সংজ্ঞায়িত করতে দেয়।

  • onElement { predicate } : একটি ডিফল্ট টাইমআউটের মধ্যে predicate এর সাথে মেলে এমন প্রথম UI উপাদান প্রদান করে৷ ফাংশনটি একটি ব্যতিক্রম নিক্ষেপ করে যদি এটি একটি মিলিত উপাদান সনাক্ত না করে।

    // Find a button with the text "Submit" and click it
    onElement { textAsString() == "Submit" }.click()
    
    // Find a UI element by its resource ID
    onElement { id == "my_button_id" }.click()
    
    // Allow a permission request
    watchFor(PermissionDialog) {
      clickAllow()
    }
    
  • onElementOrNull { predicate } : onElement এর অনুরূপ, কিন্তু যদি ফাংশনটি টাইমআউটের মধ্যে কোনো মিলিত উপাদান খুঁজে না পায় তাহলে null ফেরত দেয়। এটি একটি ব্যতিক্রম নিক্ষেপ না. ঐচ্ছিক উপাদানের জন্য এই পদ্ধতি ব্যবহার করুন.

    val optionalButton = onElementOrNull { textAsString() == "Skip" }
    optionalButton?.click() // Click only if the button exists
    
  • onElements { predicate } : অন্তত একটি UI উপাদান প্রদত্ত পূর্বনির্ধারণের সাথে মেলে না হওয়া পর্যন্ত অপেক্ষা করে, তারপর সমস্ত মিলে যাওয়া UI উপাদানগুলির একটি তালিকা প্রদান করে৷

    // Get all items in a list Ui element
    val listItems = onElements { className == "android.widget.TextView" && isClickable }
    listItems.forEach { it.click() }
    

onElement কল ব্যবহার করার জন্য এখানে কিছু টিপস রয়েছে:

  • চেইন onElement নেস্টেড উপাদানগুলির জন্য কল করে: আপনি একটি পিতামাতা-সন্তান শ্রেণিবিন্যাস অনুসরণ করে অন্যান্য উপাদানগুলির মধ্যে উপাদানগুলি খুঁজে পেতে onElement কলগুলিকে চেইন করতে পারেন৷

    // Find a parent Ui element with ID "first", then its child with ID "second",
    // then its grandchild with ID "third", and click it.
    onElement { id == "first" }
      .onElement { id == "second" }
      .onElement { id == "third" }
      .click()
    
  • মিলিসেকেন্ড প্রতিনিধিত্বকারী একটি মান পাস করে onElement* ফাংশনের জন্য একটি সময়সীমা নির্দিষ্ট করুন।

    // Find a Ui element with a zero timeout (instant check)
    onElement(0) { id == "something" }.click()
    
    // Find a Ui element with a custom timeout of 10 seconds
    onElement(10_000) { textAsString() == "Long loading text" }.click()
    

UI উপাদানগুলির সাথে ইন্টারঅ্যাক্ট করুন

ক্লিক অনুকরণ করে বা সম্পাদনাযোগ্য ক্ষেত্রগুলিতে পাঠ্য সেট করে UI উপাদানগুলির সাথে ইন্টারঅ্যাক্ট করুন৷

// Click a Ui element
onElement { textAsString() == "Tap Me" }.click()

// Set text in an editable field
onElement { className == "android.widget.EditText" }.setText("My input text")

// Perform a long click
onElement { contentDescription == "Context Menu" }.longClick()

অ্যাপের অবস্থা এবং পর্যবেক্ষকদের হ্যান্ডেল করুন

আপনার অ্যাপের জীবনচক্র পরিচালনা করুন এবং আপনার পরীক্ষার সময় উপস্থিত হতে পারে এমন অপ্রত্যাশিত UI উপাদানগুলি পরিচালনা করুন।

অ্যাপ জীবনচক্র ব্যবস্থাপনা

APIs পরীক্ষার অধীনে অ্যাপের অবস্থা নিয়ন্ত্রণ করার উপায় প্রদান করে:

// Start a specific app by package name. Used for benchmarking and other
// self-instrumenting tests.
startApp("com.example.targetapp")

// Start a specific activity within the target app
startActivity(SomeActivity::class.java)

// Start an intent
startIntent(myIntent)

// Clear the app's data (resets it to a fresh state)
clearAppData("com.example.targetapp")

অপ্রত্যাশিত UI পরিচালনা করুন

watchFor API আপনাকে অপ্রত্যাশিত UI উপাদানগুলির জন্য হ্যান্ডলারকে সংজ্ঞায়িত করতে দেয়, যেমন অনুমতি ডায়ালগ, যা আপনার পরীক্ষার প্রবাহের সময় উপস্থিত হতে পারে। এটি অভ্যন্তরীণ পর্যবেক্ষক প্রক্রিয়া ব্যবহার করে তবে আরও নমনীয়তা সরবরাহ করে।

import androidx.test.uiautomator.PermissionDialog

@Test
fun myTestWithPermissionHandling() = uiAutomator {
  startActivity(MainActivity::class.java)

  // Register a watcher to click "Allow" if a permission dialog appears
  watchFor(PermissionDialog) { clickAllow() }

  // Your test steps that might trigger a permission dialog
  onElement { textAsString() == "Request Permissions" }.click()

  // Example: You can register a different watcher later if needed
  clearAppData("com.example.targetapp")

  // Now deny permissions
  startApp("com.example.targetapp")
  watchFor(PermissionDialog) { clickDeny() }
  onElement { textAsString() == "Request Permissions" }.click()
}

PermissionDialog হল একটি ScopedWatcher<T> এর একটি উদাহরণ, যেখানে T হল একটি অবজেক্ট যা watchFor এ ব্লকের স্কোপ হিসেবে পাস করা হয়েছে। আপনি এই প্যাটার্নের উপর ভিত্তি করে কাস্টম পর্যবেক্ষক তৈরি করতে পারেন।

অ্যাপের দৃশ্যমানতা এবং স্থায়িত্বের জন্য অপেক্ষা করুন

কখনও কখনও পরীক্ষার উপাদানগুলি দৃশ্যমান বা স্থিতিশীল হওয়ার জন্য অপেক্ষা করতে হয়। UI অটোমেটর এটিতে সহায়তা করার জন্য বেশ কয়েকটি API অফার করে।

waitForAppToBeVisible("com.example.targetapp") একটি কাস্টমাইজযোগ্য সময়সীমার মধ্যে স্ক্রিনে উপস্থিত হওয়ার জন্য প্রদত্ত প্যাকেজের নাম সহ একটি UI উপাদানের জন্য অপেক্ষা করে৷

// Wait for the app to be visible after launching it
startApp("com.example.targetapp")
waitForAppToBeVisible("com.example.targetapp")

এটির সাথে ইন্টারঅ্যাক্ট করার আগে অ্যাপের UI স্থিতিশীল বলে বিবেচিত হয়েছে তা যাচাই করতে waitForStable() API ব্যবহার করুন।

// Wait for the entire active window to become stable
activeWindow().waitForStable()

// Wait for a specific Ui element to become stable (e.g., after a loading animation)
onElement { id == "my_loading_indicator" }.waitForStable()

উন্নত বৈশিষ্ট্য

নিম্নলিখিত বৈশিষ্ট্যগুলি আরও জটিল পরীক্ষার পরিস্থিতিতে উপযোগী।

একাধিক উইন্ডোর সাথে ইন্টারঅ্যাক্ট করুন

UI অটোমেটর API গুলি আপনাকে সরাসরি ইন্টারঅ্যাক্ট করতে এবং UI উপাদানগুলি পরিদর্শন করতে দেয়৷ এটি একাধিক উইন্ডোর সাথে জড়িত পরিস্থিতির জন্য বিশেষভাবে উপযোগী, যেমন পিকচার-ইন-পিকচার (পিআইপি) মোড বা স্প্লিট-স্ক্রিন লেআউট।

// Find the first window that is in Picture-in-Picture mode
val pipWindow = windows()
  .first { it.isInPictureInPictureMode == true }

// Now you can interact with elements within that specific window
pipWindow.onElement { textAsString() == "Play" }.click()

স্ক্রিনশট এবং ভিজ্যুয়াল দাবী

সম্পূর্ণ স্ক্রীনের স্ক্রিনশট ক্যাপচার করুন, নির্দিষ্ট উইন্ডোজ বা পৃথক UI উপাদানগুলি সরাসরি আপনার পরীক্ষার মধ্যে। এটি ভিজ্যুয়াল রিগ্রেশন টেস্টিং এবং ডিবাগিংয়ের জন্য সহায়ক।

uiautomator {
  // Take a screenshot of the entire active window
  val fullScreenBitmap: Bitmap = activeWindow().takeScreenshot()
  fullScreenBitmap.saveToFile(File("/sdcard/Download/full_screen.png"))

  // Take a screenshot of a specific UI element (e.g., a button)
  val buttonBitmap: Bitmap = onElement { id == "my_button" }.takeScreenshot()
  buttonBitmap.saveToFile(File("/sdcard/Download/my_button_screenshot.png"))

  // Example: Take a screenshot of a PiP window
  val pipWindowScreenshot = windows()
    .first { it.isInPictureInPictureMode == true }
    .takeScreenshot()
  pipWindowScreenshot.saveToFile(File("/sdcard/Download/pip_screenshot.png"))
}

বিটম্যাপের জন্য saveToFile এক্সটেনশন ফাংশন ক্যাপচার করা ছবিকে একটি নির্দিষ্ট পথে সংরক্ষণ করা সহজ করে।

ডিবাগিং এর জন্য ResultsReporter ব্যবহার করুন

ResultsReporter আপনাকে সহজতর পরিদর্শন এবং ডিবাগিংয়ের জন্য Android স্টুডিওতে আপনার পরীক্ষার ফলাফলের সাথে সরাসরি স্ক্রিনশটের মতো পরীক্ষা নিদর্শন সংযুক্ত করতে সহায়তা করে।

uiAutomator {
  startApp("com.example.targetapp")

  val reporter = ResultsReporter("MyTestArtifacts") // Name for this set of results
  val file = reporter.addNewFile(
    filename = "my_screenshot",
    title = "Accessible button image" // Title that appears in Android Studio test results
  )

  // Take a screenshot of an element and save it using the reporter
  onElement { textAsString() == "Accessible button" }
    .takeScreenshot()
    .saveToFile(file)

  // Report the artifacts to instrumentation, making them visible in Android Studio
  reporter.reportToInstrumentation()
}

পুরানো UI অটোমেটর সংস্করণগুলি থেকে স্থানান্তর করুন৷

আপনার যদি পুরানো API পৃষ্ঠের সাথে লেখা বিদ্যমান UI অটোমেটর পরীক্ষা থাকে, তাহলে আধুনিক পদ্ধতিতে স্থানান্তরিত করার জন্য একটি রেফারেন্স হিসাবে নিম্নলিখিত টেবিলটি ব্যবহার করুন:

কর্মের ধরন পুরানো UI অটোমেটর পদ্ধতি নতুন UI অটোমেটর পদ্ধতি
এন্ট্রি পয়েন্ট UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) uiAutomator { ... } স্কোপে টেস্ট লজিক মোড়ানো।
UI উপাদান খুঁজুন device.findObject(By.res("com.example.app:id/my_button")) onElement { id == "my\_button" }
UI উপাদান খুঁজুন device.findObject(By.text("Click Me")) onElement { textAsString() == "Click Me" }
নিষ্ক্রিয় UI এর জন্য অপেক্ষা করুন device.waitForIdle() onElement এর বিল্ট-ইন টাইমআউট মেকানিজম পছন্দ করুন; অন্যথায়, activeWindow().waitForStable()
শিশু উপাদান খুঁজুন ম্যানুয়ালি নেস্ট করা findObject কল onElement().onElement() চেইনিং
অনুমতি ডায়ালগ পরিচালনা করুন UiAutomator.registerWatcher() watchFor(PermissionDialog)