UI অটোমেটর লিগ্যাসি API ব্যবহার করুন

UI Automator হলো একটি UI টেস্টিং ফ্রেমওয়ার্ক যা সিস্টেম এবং ইনস্টল করা অ্যাপগুলোর মধ্যে ক্রস-অ্যাপ ফাংশনাল UI টেস্টিংয়ের জন্য উপযুক্ত। UI Automator API-গুলো আপনাকে ডিভাইসের দৃশ্যমান এলিমেন্টগুলোর সাথে ইন্টারঅ্যাক্ট করার সুযোগ দেয়, কোন Activity ফোকাসে আছে তা নির্বিশেষে। ফলে, এটি আপনাকে একটি টেস্ট ডিভাইসে সেটিংস মেনু বা অ্যাপ লঞ্চার খোলার মতো অপারেশনগুলো সম্পাদন করতে দেয়। আপনার টেস্টটি কোনো UI কম্পোনেন্টে প্রদর্শিত টেক্সট বা তার কন্টেন্ট ডেসক্রিপশনের মতো সুবিধাজনক ডেসক্রিপ্টর ব্যবহার করে কম্পোনেন্টটি খুঁজে বের করতে পারে।

UI Automator টেস্টিং ফ্রেমওয়ার্কটি একটি ইন্সট্রুমেন্টেশন-ভিত্তিক API এবং এটি AndroidJUnitRunner টেস্ট রানারের সাথে কাজ করে। এটি অপেক বক্স-স্টাইল অটোমেটেড টেস্ট লেখার জন্য বিশেষভাবে উপযোগী, যেখানে টেস্ট কোডটি টার্গেট অ্যাপের অভ্যন্তরীণ বাস্তবায়নের বিবরণের উপর নির্ভর করে না।

UI Automator টেস্টিং ফ্রেমওয়ার্কের প্রধান বৈশিষ্ট্যগুলো হলো নিম্নরূপ:

  • টার্গেট ডিভাইসের অবস্থার তথ্য পুনরুদ্ধার করতে এবং তাতে বিভিন্ন অপারেশন সম্পাদন করার জন্য একটি এপিআই। আরও তথ্যের জন্য, ‘ডিভাইসের অবস্থা অ্যাক্সেস করা’ দেখুন।
  • এপিআই যা ক্রস-অ্যাপ UI টেস্টিং সমর্থন করে। আরও তথ্যের জন্য, UI অটোমেটর এপিআই দেখুন।

ডিভাইসের অবস্থা অ্যাক্সেস করা

UI Automator টেস্টিং ফ্রেমওয়ার্কটি একটি UiDevice ক্লাস প্রদান করে, যার মাধ্যমে টার্গেট অ্যাপটি যে ডিভাইসে চলছে, সেই ডিভাইসটি অ্যাক্সেস করা এবং তাতে বিভিন্ন অপারেশন সম্পাদন করা যায়। আপনি এর মেথডগুলো কল করে ডিভাইসের প্রোপার্টি, যেমন বর্তমান ওরিয়েন্টেশন বা ডিসপ্লে সাইজ, অ্যাক্সেস করতে পারেন। UiDevice ক্লাসটি আপনাকে নিম্নলিখিত কাজগুলোও করতে দেয়:

  1. ডিভাইসটির ঘূর্ণন পরিবর্তন করুন।
  2. 'ভলিউম আপ'-এর মতো হার্ডওয়্যার কীগুলো চাপুন।
  3. ব্যাক, হোম বা মেনু বাটন চাপুন।
  4. নোটিফিকেশন শেডটি খুলুন।
  5. বর্তমান উইন্ডোটির একটি স্ক্রিনশট নিন।

উদাহরণস্বরূপ, হোম বাটন চাপার অনুকরণ করতে, UiDevice.pressHome() মেথডটি কল করুন।

UI অটোমেটর এপিআই

UI Automator API-গুলো আপনাকে টার্গেট করা অ্যাপটির ইমপ্লিমেন্টেশন ডিটেইলস না জেনেই শক্তিশালী টেস্ট লেখার সুযোগ দেয়। আপনি এই API-গুলো ব্যবহার করে একাধিক অ্যাপ জুড়ে UI কম্পোনেন্টগুলো ক্যাপচার এবং ম্যানিপুলেট করতে পারেন:

  • UiObject2 : ডিভাইসে দৃশ্যমান একটি UI উপাদানকে বোঝায়।
  • BySelector : UI এলিমেন্ট মেলানোর জন্য মানদণ্ড নির্দিষ্ট করে।
  • By : BySelector সংক্ষিপ্তভাবে গঠন করে।
  • Configurator : এর মাধ্যমে আপনি UI অটোমেটর টেস্ট চালানোর জন্য মূল প্যারামিটারগুলো সেট করতে পারবেন।

উদাহরণস্বরূপ, নিচের কোডটি দেখায় যে আপনি কীভাবে একটি টেস্ট স্ক্রিপ্ট লিখতে পারেন যা ডিভাইসে একটি Gmail অ্যাপ খোলে:

কোটলিন

device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressHome()

val gmail: UiObject2 = device.findObject(By.text("Gmail"))
// Perform a click and wait until the app is opened.
val opened: Boolean = gmail.clickAndWait(Until.newWindow(), 3000)
assertThat(opened).isTrue()

জাভা

device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.pressHome();

UiObject2 gmail = device.findObject(By.text("Gmail"));
// Perform a click and wait until the app is opened.
Boolean opened = gmail.clickAndWait(Until.newWindow(), 3000);
assertTrue(opened);

UI অটোমেটর সেট আপ করুন

UI Automator দিয়ে আপনার UI টেস্ট তৈরি করার আগে, "AndroidX টেস্টের জন্য প্রজেক্ট সেট আপ করুন" অংশে বর্ণিত পদ্ধতি অনুযায়ী আপনার টেস্ট সোর্স কোডের অবস্থান এবং প্রজেক্টের নির্ভরতাগুলো কনফিগার করে নিন।

আপনার অ্যান্ড্রয়েড অ্যাপ মডিউলের build.gradle ফাইলে, আপনাকে অবশ্যই UI Automator লাইব্রেরির একটি ডিপেন্ডেন্সি রেফারেন্স সেট করতে হবে:

কোটলিন

dependencies { ... androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0") }

গ্রুভি

dependencies { ... androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0" }

আপনার UI Automator টেস্টিং অপ্টিমাইজ করার জন্য, প্রথমে টার্গেট অ্যাপের UI কম্পোনেন্টগুলো পরিদর্শন করে নিশ্চিত করতে হবে যে সেগুলো অ্যাক্সেসযোগ্য। এই অপ্টিমাইজেশন টিপসগুলো পরবর্তী দুটি বিভাগে বর্ণনা করা হয়েছে।

ডিভাইসে UI পরিদর্শন করুন

আপনার টেস্ট ডিজাইন করার আগে, ডিভাইসে দৃশ্যমান UI কম্পোনেন্টগুলো পরিদর্শন করুন। আপনার UI Automator টেস্টগুলো যাতে এই কম্পোনেন্টগুলো অ্যাক্সেস করতে পারে, তা নিশ্চিত করতে যাচাই করুন যে এই কম্পোনেন্টগুলোতে দৃশ্যমান টেক্সট লেবেল, android:contentDescription ভ্যালু, অথবা উভয়ই আছে।

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

uiautomatorviewer টুলটি চালু করতে:

  1. একটি বাস্তব ডিভাইসে কাঙ্ক্ষিত অ্যাপটি চালু করুন।
  2. ডিভাইসটি আপনার ডেভেলপমেন্ট মেশিনের সাথে সংযুক্ত করুন।
  3. একটি টার্মিনাল উইন্ডো খুলুন এবং <android-sdk>/tools/ ডিরেক্টরিতে যান।
  4. এই কমান্ড দিয়ে টুলটি চালান:
 $ uiautomatorviewer

আপনার অ্যাপ্লিকেশনের UI প্রোপার্টিগুলো দেখতে:

  1. uiautomatorviewer ইন্টারফেসে, ডিভাইস স্ক্রিনশট বোতামটিতে ক্লিক করুন।
  2. uiautomatorviewer টুল দ্বারা চিহ্নিত UI উপাদানগুলো দেখতে বাম দিকের প্যানেলে থাকা স্ন্যাপশটটির উপর মাউস রাখুন। প্রোপার্টিগুলো নিচের ডান দিকের প্যানেলে এবং লেআউটের স্তরবিন্যাস উপরের ডান দিকের প্যানেলে তালিকাভুক্ত থাকে।
  3. ঐচ্ছিকভাবে, UI Automator-এর নাগালের বাইরে থাকা UI কম্পোনেন্টগুলো দেখতে 'Toggle NAF Nodes' বোতামে ক্লিক করুন। এই কম্পোনেন্টগুলোর জন্য শুধুমাত্র সীমিত তথ্য উপলব্ধ থাকতে পারে।

অ্যান্ড্রয়েড দ্বারা প্রদত্ত সাধারণ ধরনের UI উপাদানগুলো সম্পর্কে জানতে, ইউজার ইন্টারফেস দেখুন।

আপনার কার্যক্রমটি যেন সকলের জন্য সহজলভ্য হয় তা নিশ্চিত করুন।

UI Automator টেস্ট ফ্রেমওয়ার্কটি সেইসব অ্যাপে আরও ভালোভাবে কাজ করে, যেগুলোতে অ্যান্ড্রয়েড অ্যাক্সেসিবিলিটি ফিচারগুলো প্রয়োগ করা হয়েছে। আপনি যখন SDK থেকে View টাইপের UI এলিমেন্ট, বা View এর কোনো সাবক্লাস ব্যবহার করেন, তখন আপনাকে অ্যাক্সেসিবিলিটি সাপোর্ট প্রয়োগ করতে হয় না, কারণ এই ক্লাসগুলো আপনার জন্য তা আগে থেকেই করে রেখেছে।

তবে, কিছু অ্যাপ আরও উন্নত ইউজার এক্সপেরিয়েন্স দেওয়ার জন্য কাস্টম UI এলিমেন্ট ব্যবহার করে। এই ধরনের এলিমেন্টগুলো স্বয়ংক্রিয়ভাবে অ্যাক্সেসিবিলিটি সাপোর্ট দেয় না। যদি আপনার অ্যাপে SDK-এর বাইরের View এর কোনো সাবক্লাসের ইনস্ট্যান্স থাকে, তাহলে নিম্নলিখিত ধাপগুলো সম্পন্ন করে এই এলিমেন্টগুলোতে অ্যাক্সেসিবিলিটি ফিচার যোগ করা নিশ্চিত করুন:

  1. একটি কনক্রিট ক্লাস তৈরি করুন যা ExploreByTouchHelper ক্লাসটিকে এক্সটেন্ড করে।
  2. setAccessibilityDelegate() কল করে আপনার নতুন ক্লাসের একটি ইনস্ট্যান্সকে একটি নির্দিষ্ট কাস্টম UI এলিমেন্টের সাথে যুক্ত করুন।

কাস্টম ভিউ এলিমেন্টগুলিতে অ্যাক্সেসিবিলিটি বৈশিষ্ট্য যোগ করার বিষয়ে অতিরিক্ত নির্দেশনার জন্য, "অ্যাক্সেসযোগ্য কাস্টম ভিউ তৈরি করা" দেখুন। অ্যান্ড্রয়েডে অ্যাক্সেসিবিলিটির সাধারণ সেরা অনুশীলন সম্পর্কে আরও জানতে, "অ্যাপগুলিকে আরও অ্যাক্সেসযোগ্য করা" দেখুন।

একটি UI অটোমেটর টেস্ট ক্লাস তৈরি করুন

আপনার UI Automator টেস্ট ক্লাসটি একটি JUnit 4 টেস্ট ক্লাসের মতোই লেখা উচিত। JUnit 4 টেস্ট ক্লাস তৈরি করা এবং JUnit 4 অ্যাসারশন ও অ্যানোটেশন ব্যবহার সম্পর্কে আরও জানতে, "Create an Instrumented Unit Test Class" দেখুন।

আপনার টেস্ট ক্লাস ডেফিনিশনের শুরুতে @RunWith(AndroidJUnit4.class) অ্যানোটেশনটি যোগ করুন। এছাড়াও, আপনাকে AndroidX Test-এ দেওয়া AndroidJUnitRunner ক্লাসটিকে আপনার ডিফল্ট টেস্ট রানার হিসেবে নির্দিষ্ট করতে হবে। এই ধাপটি "একটি ডিভাইস বা এমুলেটরে UI Automator টেস্ট চালান" অংশে আরও বিস্তারিতভাবে বর্ণনা করা হয়েছে।

আপনার UI Automator টেস্ট ক্লাসে নিম্নলিখিত প্রোগ্রামিং মডেলটি প্রয়োগ করুন:

  1. যে ডিভাইসটি পরীক্ষা করতে চান, সেটি অ্যাক্সেস করার জন্য getInstance() মেথডটি কল করুন এবং আর্গুমেন্ট হিসেবে একটি Instrumentation অবজেক্ট পাস করে একটি UiDevice অবজেক্ট নিন।
  2. ডিভাইসে প্রদর্শিত কোনো UI কম্পোনেন্ট (যেমন, ফোরগ্রাউন্ডে থাকা বর্তমান ভিউ) অ্যাক্সেস করতে, findObject() মেথডটি কল করে একটি UiObject2 অবজেক্ট পান।
  3. একটি UiObject2 মেথড কল করার মাধ্যমে সেই UI কম্পোনেন্টটিতে একটি নির্দিষ্ট ইউজার ইন্টারঅ্যাকশন সিমুলেট করুন; উদাহরণস্বরূপ, স্ক্রল করার জন্য scrollUntil() এবং একটি টেক্সট ফিল্ড এডিট করার জন্য setText() কল করুন। একাধিক UI কম্পোনেন্ট বা ইউজার অ্যাকশনের ক্রম জড়িত আরও জটিল ইউজার ইন্টারঅ্যাকশন পরীক্ষা করার জন্য আপনি প্রয়োজন অনুযায়ী ধাপ ২ এবং ৩-এর API-গুলো বারবার কল করতে পারেন।
  4. এই ব্যবহারকারী ইন্টারঅ্যাকশনগুলি সম্পন্ন হওয়ার পরে, UI প্রত্যাশিত অবস্থা বা আচরণ প্রতিফলিত করছে কিনা তা যাচাই করুন।

এই ধাপগুলো নিচের বিভাগগুলোতে আরও বিস্তারিতভাবে আলোচনা করা হয়েছে।

UI উপাদান অ্যাক্সেস করুন

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

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

নিম্নলিখিত কোড স্নিপেটটি দেখায় যে কীভাবে আপনার টেস্টটি UiDevice এর একটি ইনস্ট্যান্স পেতে পারে এবং হোম বাটন চাপার অনুকরণ করতে পারে:

কোটলিন

import org.junit.Before
import androidx.test.runner.AndroidJUnit4
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
...

private const val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample"
private const val LAUNCH_TIMEOUT = 5000L
private const val STRING_TO_BE_TYPED = "UiAutomator"

@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 18)
class ChangeTextBehaviorTest2 {

private lateinit var device: UiDevice

@Before
fun startMainActivityFromHomeScreen() {
  // Initialize UiDevice instance
  device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

  // Start from the home screen
  device.pressHome()

  // Wait for launcher
  val launcherPackage: String = device.launcherPackageName
  assertThat(launcherPackage, notNullValue())
  device.wait(
    Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT
  )

  // Launch the app
  val context = ApplicationProvider.getApplicationContext<Context>()
  val intent = context.packageManager.getLaunchIntentForPackage(
  BASIC_SAMPLE_PACKAGE).apply {
    // Clear out any previous instances
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  context.startActivity(intent)

  // Wait for the app to appear
  device.wait(
    Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT
    )
  }
}

জাভা

import org.junit.Before;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Until;
...

@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class ChangeTextBehaviorTest {

  private static final String BASIC_SAMPLE_PACKAGE
  = "com.example.android.testing.uiautomator.BasicSample";
  private static final int LAUNCH_TIMEOUT = 5000;
  private static final String STRING_TO_BE_TYPED = "UiAutomator";
  private UiDevice device;

  @Before
  public void startMainActivityFromHomeScreen() {
    // Initialize UiDevice instance
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    // Start from the home screen
    device.pressHome();

    // Wait for launcher
    final String launcherPackage = device.getLauncherPackageName();
    assertThat(launcherPackage, notNullValue());
    device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT);

    // Launch the app
    Context context = ApplicationProvider.getApplicationContext();
    final Intent intent = context.getPackageManager()
    .getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
    // Clear out any previous instances
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);

    // Wait for the app to appear
    device.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT);
    }
}

উদাহরণটিতে, @SdkSuppress(minSdkVersion = 18) স্টেটমেন্টটি নিশ্চিত করে যে টেস্টগুলো শুধুমাত্র অ্যান্ড্রয়েড ৪.৩ (এপিআই লেভেল ১৮) বা তার উচ্চতর সংস্করণের ডিভাইসেই রান করবে, যা UI Automator ফ্রেমওয়ার্কের জন্য আবশ্যক।

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

নিম্নলিখিত কোড স্নিপেটটি দেখায় যে কীভাবে আপনার টেস্ট একটি অ্যাপের Cancel বাটন এবং OK বাটনকে প্রতিনিধিত্বকারী UiObject2 ইনস্ট্যান্স তৈরি করতে পারে।

কোটলিন

val okButton: UiObject2 = device.findObject(
    By.text("OK").clazz("android.widget.Button")
)

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click()
}

জাভা

UiObject2 okButton = device.findObject(
    By.text("OK").clazz("android.widget.Button")
);

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click();
}

একটি নির্বাচক নির্দিষ্ট করুন

অ্যাপের কোনো নির্দিষ্ট UI কম্পোনেন্ট অ্যাক্সেস করতে চাইলে, BySelector ইনস্ট্যান্স তৈরি করার জন্য By ক্লাসটি ব্যবহার করুন। BySelector প্রদর্শিত UI-এর নির্দিষ্ট এলিমেন্টগুলোর জন্য একটি কোয়েরি উপস্থাপন করে।

যদি একাধিক মিলে যাওয়া এলিমেন্ট পাওয়া যায়, তাহলে লেআউট হায়ারার্কিতে থাকা প্রথম মিলে যাওয়া এলিমেন্টটিকে টার্গেট UiObject2 হিসেবে রিটার্ন করা হয়। একটি BySelector তৈরি করার সময়, আপনি আপনার সার্চকে আরও সুনির্দিষ্ট করতে একাধিক প্রপার্টি একসাথে জুড়ে দিতে পারেন। যদি মিলে যাওয়া কোনো UI এলিমেন্ট খুঁজে না পাওয়া যায়, তাহলে null রিটার্ন করা হয়।

আপনি একাধিক BySelector ইনস্ট্যান্সকে নেস্ট করার জন্য hasChild() বা hasDescendant() মেথড ব্যবহার করতে পারেন। উদাহরণস্বরূপ, নিম্নলিখিত কোড উদাহরণটি দেখায় যে কীভাবে আপনার টেস্টটি এমন প্রথম ListView খুঁজে বের করার জন্য একটি সার্চ নির্দিষ্ট করতে পারে, যার একটি চাইল্ড UI এলিমেন্টের `text` প্রপার্টি রয়েছে।

কোটলিন

val listView: UiObject2 = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
)

জাভা

UiObject2 listView = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
);

আপনার সিলেক্টর ক্রাইটেরিয়াতে অবজেক্টের অবস্থা নির্দিষ্ট করে দেওয়াটা সুবিধাজনক হতে পারে। উদাহরণস্বরূপ, যদি আপনি চেক করা সমস্ত এলিমেন্টের একটি তালিকা সিলেক্ট করে সেগুলোকে আনচেক করতে চান, তাহলে ` checked() ` মেথডটিকে `true` আর্গুমেন্ট দিয়ে কল করুন।

কাজ সম্পাদন করুন

আপনার টেস্ট একবার একটি UiObject2 অবজেক্ট পেয়ে গেলে, আপনি সেই অবজেক্ট দ্বারা প্রতিনিধিত্ব করা UI কম্পোনেন্টের উপর ব্যবহারকারীর কার্যকলাপ সম্পাদন করার জন্য UiObject2 ক্লাসের মেথডগুলো কল করতে পারেন। আপনি নিম্নলিখিত ধরনের অ্যাকশনগুলো নির্দিষ্ট করতে পারেন:

  • click() : UI এলিমেন্টের দৃশ্যমান সীমানার কেন্দ্রস্থলে ক্লিক করে।
  • drag() : এই অবজেক্টটিকে যেকোনো স্থানাঙ্কে টেনে নিয়ে যায়।
  • setText() : কোনো সম্পাদনাযোগ্য ফিল্ডের বিষয়বস্তু মুছে ফেলার পর, সেই ফিল্ডে টেক্সট সেট করে। এর বিপরীতে, clear() মেথডটি কোনো সম্পাদনাযোগ্য ফিল্ডের বিদ্যমান টেক্সট মুছে ফেলে।
  • swipe() : নির্দিষ্ট দিকে সোয়াইপ করার কাজটি সম্পাদন করে।
  • scrollUntil() : Condition বা EventCondition পূরণ না হওয়া পর্যন্ত নির্দিষ্ট দিকে স্ক্রল অ্যাকশনটি সম্পাদন করে।

UI Automator টেস্টিং ফ্রেমওয়ার্ক আপনাকে getContext() এর মাধ্যমে একটি Context অবজেক্ট পাওয়ার ফলে, শেল কমান্ড ব্যবহার না করেই একটি Intent পাঠাতে বা একটি Activity চালু করতে দেয়।

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

কোটলিন

fun setUp() {
...

  // Launch a simple calculator app
  val context = getInstrumentation().context
  val intent = context.packageManager.getLaunchIntentForPackage(CALC_PACKAGE).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  // Clear out any previous instances
  context.startActivity(intent)
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT)
}

জাভা

public void setUp() {
...

  // Launch a simple calculator app
  Context context = getInstrumentation().getContext();
  Intent intent = context.getPackageManager()
  .getLaunchIntentForPackage(CALC_PACKAGE);
  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

  // Clear out any previous instances
  context.startActivity(intent);
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT);
}

ফলাফল যাচাই করুন

InstrumentationTestCase, TestCase-কে এক্সটেন্ড করে, তাই আপনি অ্যাপের UI কম্পোনেন্টগুলো প্রত্যাশিত ফলাফল দিচ্ছে কিনা তা পরীক্ষা করার জন্য স্ট্যান্ডার্ড JUnit Assert মেথড ব্যবহার করতে পারেন।

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে আপনার পরীক্ষা একটি ক্যালকুলেটর অ্যাপে একাধিক বোতাম খুঁজে বের করতে পারে, সেগুলিতে ক্রমানুসারে ক্লিক করতে পারে এবং তারপরে সঠিক ফলাফল প্রদর্শিত হচ্ছে কিনা তা যাচাই করতে পারে।

কোটলিন

private const val CALC_PACKAGE = "com.myexample.calc"

fun testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click()
  device.findObject(By.res(CALC_PACKAGE, "plus")).click()
  device.findObject(By.res(CALC_PACKAGE, "three")).click()
  device.findObject(By.res(CALC_PACKAGE, "equals")).click()

  // Verify the result = 5
  val result: UiObject2 = device.findObject(By.res(CALC_PACKAGE, "result"))
  assertEquals("5", result.text)
}

জাভা

private static final String CALC_PACKAGE = "com.myexample.calc";

public void testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click();
  device.findObject(By.res(CALC_PACKAGE, "plus")).click();
  device.findObject(By.res(CALC_PACKAGE, "three")).click();
  device.findObject(By.res(CALC_PACKAGE, "equals")).click();

  // Verify the result = 5
  UiObject2 result = device.findObject(By.res(CALC_PACKAGE, "result"));
  assertEquals("5", result.getText());
}

ডিভাইস বা এমুলেটরে UI অটোমেটর টেস্টগুলো চালান

আপনি অ্যান্ড্রয়েড স্টুডিও অথবা কমান্ড-লাইন থেকে UI অটোমেটর টেস্টগুলো চালাতে পারেন। আপনার প্রোজেক্টে ডিফল্ট ইন্সট্রুমেন্টেশন রানার হিসেবে AndroidJUnitRunner নির্দিষ্ট করে দিতে ভুলবেন না।

আরও উদাহরণ

সিস্টেম UI-এর সাথে ইন্টারঅ্যাক্ট করুন

নিম্নলিখিত কোড স্নিপেটগুলিতে যেমন দেখানো হয়েছে, UI Automator স্ক্রিনের সবকিছুর সাথে ইন্টারঅ্যাক্ট করতে পারে, যার মধ্যে আপনার অ্যাপের বাইরের সিস্টেম এলিমেন্টগুলোও অন্তর্ভুক্ত।

কোটলিন

// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.executeShellCommand("am start -a android.settings.SETTINGS")

জাভা

// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.executeShellCommand("am start -a android.settings.SETTINGS");

কোটলিন

// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openNotification()

জাভা

// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openNotification();

কোটলিন

// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openQuickSettings()

জাভা

// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openQuickSettings();

কোটলিন

// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"))
print(clock.getText())

জাভা

// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"));
print(clock.getText());

পরিবর্তনের জন্য অপেক্ষা করুন

বিরক্তি বন্ধ করুন
চিত্র ১. UI Automator একটি পরীক্ষামূলক ডিভাইসে ডু নট ডিস্টার্ব মোড বন্ধ করে দিচ্ছে।

স্ক্রিন পরিবর্তনে সময় লাগতে পারে এবং এর সময়কাল অনুমান করা নির্ভরযোগ্য নয়, তাই অপারেশন সম্পাদনের পর UI Automator-কে অপেক্ষা করানো উচিত। এর জন্য UI Automator একাধিক পদ্ধতি প্রদান করে:

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে UI Automator ব্যবহার করে সিস্টেম সেটিংসে ডু নট ডিস্টার্ব মোড বন্ধ করতে হয়, যেখানে ট্রানজিশনের জন্য অপেক্ষা করে এমন performActionAndWait() মেথডটি ব্যবহার করা হয়েছে:

কোটলিন

@Test
@SdkSuppress(minSdkVersion = 21)
@Throws(Exception::class)
fun turnOffDoNotDisturb() {
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
    device.performActionAndWait({
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS")
        } catch (e: IOException) {
            throw RuntimeException(e)
        }
    }, Until.newWindow(), 1000)
    // Check system settings has been opened.
    Assert.assertTrue(device.hasObject(By.pkg("com.android.settings")))

    // Scroll the settings to the top and find Notifications button
    var scrollableObj: UiObject2 = device.findObject(By.scrollable(true))
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP))
    val notificationsButton = scrollableObj.findObject(By.text("Notifications"))

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait({ notificationsButton.click() }, Until.newWindow(), 1000)
    scrollableObj = device.findObject(By.scrollable(true))
    // Scroll down until it finds a Do Not Disturb button.
    val doNotDisturb = scrollableObj.scrollUntil(
        Direction.DOWN,
        Until.findObject(By.textContains("Do Not Disturb"))
    )
    device.performActionAndWait({ doNotDisturb.click() }, Until.newWindow(), 1000)
    // Turn off the Do Not Disturb.
    val turnOnDoNotDisturb = device.findObject(By.text("Turn on now"))
    turnOnDoNotDisturb?.click()
    Assert.assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000))
}

জাভা

@Test
@SdkSuppress(minSdkVersion = 21)
public void turnOffDoNotDisturb() throws Exception{
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    device.performActionAndWait(() -> {
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }, Until.newWindow(), 1000);
    // Check system settings has been opened.
    assertTrue(device.hasObject(By.pkg("com.android.settings")));

    // Scroll the settings to the top and find Notifications button
    UiObject2 scrollableObj = device.findObject(By.scrollable(true));
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP));
    UiObject2 notificationsButton = scrollableObj.findObject(By.text("Notifications"));

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait(() -> notificationsButton.click(), Until.newWindow(), 1000);
    scrollableObj = device.findObject(By.scrollable(true));
    // Scroll down until it finds a Do Not Disturb button.
    UiObject2 doNotDisturb = scrollableObj.scrollUntil(Direction.DOWN,
            Until.findObject(By.textContains("Do Not Disturb")));
    device.performActionAndWait(()-> doNotDisturb.click(), Until.newWindow(), 1000);
    // Turn off the Do Not Disturb.
    UiObject2 turnOnDoNotDisturb = device.findObject(By.text("Turn on now"));
    if(turnOnDoNotDisturb != null) {
        turnOnDoNotDisturb.click();
    }
    assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000));
}

অতিরিক্ত সম্পদ

অ্যান্ড্রয়েড টেস্টে UI Automator ব্যবহার সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত রিসোর্সগুলো দেখুন।

রেফারেন্স ডকুমেন্টেশন:

নমুনা

  • BasicSample : বেসিক UI অটোমেটরের নমুনা।