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

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

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

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

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

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

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

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

আধুনিক UI Automator 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 Automator API এর মূল ধারণাগুলি বর্ণনা করে।

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

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

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

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

UI উপাদানগুলি সনাক্ত করতে UI Automator API ব্যবহার করুন। এই pricates আপনাকে পাঠ্য, নির্বাচিত বা ফোকাস করা অবস্থা এবং বিষয়বস্তুর বিবরণের মতো বৈশিষ্ট্যের জন্য শর্ত নির্ধারণ করতে দেয়।

  • 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 { viewIdResourceName == "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 } : প্রদত্ত 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 { viewIdResourceName == "first" }
      .onElement { viewIdResourceName == "second" }
      .onElement { viewIdResourceName == "third" }
      .click()
    
  • মিলিসেকেন্ড প্রতিনিধিত্বকারী একটি মান পাস করে onElement* ফাংশনের জন্য একটি টাইমআউট নির্দিষ্ট করুন।

    // Find a Ui element with a zero timeout (instant check)
    onElement(0) { viewIdResourceName == "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 উপাদানগুলি পরিচালনা করুন।

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

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

// 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 Automator এই ক্ষেত্রে সাহায্য করার জন্য বেশ কয়েকটি API অফার করে।

waitForAppToBeVisible("com.example.targetapp") একটি কাস্টমাইজেবল টাইমআউটের মধ্যে স্ক্রিনে প্রদত্ত প্যাকেজ নামের একটি UI উপাদান প্রদর্শিত হওয়ার জন্য অপেক্ষা করে।

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

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

// 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 { viewIdResourceName == "my_loading_indicator" }.waitForStable()

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

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

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

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

// 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 { viewIdResourceName == "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 Studio-তে আপনার পরীক্ষার ফলাফলের সাথে স্ক্রিনশটের মতো পরীক্ষার আর্টিফ্যাক্টগুলিকে সরাসরি সংযুক্ত করতে সাহায্য করে।

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 Automator সংস্করণ থেকে স্থানান্তর করুন

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

অ্যাকশনের ধরণ পুরাতন UI অটোমেটর পদ্ধতি নতুন UI অটোমেটর পদ্ধতি
প্রবেশ বিন্দু UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) uiAutomator { ... } স্কোপে পরীক্ষার লজিক মোড়ানো।
UI উপাদান খুঁজুন device.findObject(By.res("com.example.app:id/my_button")) onElement { viewIdResourceName == "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)