UI Automator یک چارچوب تست رابط کاربری است که برای تست رابط کاربری عملکردی بین برنامهای در سراسر سیستم و برنامههای نصب شده مناسب است. APIهای UI Automator به شما امکان میدهند با عناصر قابل مشاهده در یک دستگاه، صرف نظر از اینکه کدام Activity در کانون توجه است، تعامل داشته باشید، بنابراین به شما امکان میدهد عملیاتی مانند باز کردن منوی تنظیمات یا لانچر برنامه را در یک دستگاه آزمایشی انجام دهید. تست شما میتواند با استفاده از توصیفگرهای مناسب مانند متن نمایش داده شده در آن مؤلفه یا توضیحات محتوای آن، یک مؤلفه رابط کاربری را جستجو کند.
چارچوب تست UI Automator یک API مبتنی بر ابزار دقیق است و با اجراکننده تست AndroidJUnitRunner کار میکند. این چارچوب برای نوشتن تستهای خودکار به سبک جعبهای مبهم، که در آن کد تست به جزئیات پیادهسازی داخلی برنامه هدف متکی نیست، بسیار مناسب است.
ویژگیهای کلیدی چارچوب تست UI Automator شامل موارد زیر است:
- یک API برای بازیابی اطلاعات وضعیت و انجام عملیات روی دستگاه هدف. برای اطلاعات بیشتر، به بخش دسترسی به وضعیت دستگاه مراجعه کنید.
- APIهایی که از تست رابط کاربری بین اپلیکیشنی پشتیبانی میکنند. برای اطلاعات بیشتر، به APIهای UI Automator مراجعه کنید.
دسترسی به وضعیت دستگاه
چارچوب تست UI Automator یک کلاس UiDevice برای دسترسی و انجام عملیات روی دستگاهی که برنامه هدف روی آن اجرا میشود، ارائه میدهد. میتوانید متدهای آن را برای دسترسی به ویژگیهای دستگاه مانند جهت فعلی یا اندازه صفحه نمایش فراخوانی کنید. کلاس UiDevice همچنین به شما امکان میدهد اقدامات زیر را انجام دهید:
- چرخش دستگاه را تغییر دهید.
- کلیدهای سختافزاری مانند «افزایش صدا» را فشار دهید.
- دکمههای برگشت، خانه یا منو را فشار دهید.
- نوار اعلانها را باز کنید.
- از پنجره فعلی اسکرین شات بگیرید.
برای مثال، برای شبیهسازی فشردن دکمهی Home، متد UiDevice.pressHome() را فراخوانی کنید.
رابطهای برنامهنویسی خودکار رابط کاربری
رابطهای برنامهنویسی کاربردی (API) خودکارساز رابط کاربری (UI Automator) به شما امکان میدهند بدون نیاز به دانستن جزئیات پیادهسازی برنامهای که هدف قرار دادهاید، تستهای قوی بنویسید. میتوانید از این APIها برای ثبت و دستکاری اجزای رابط کاربری در چندین برنامه استفاده کنید:
-
UiObject2: نشاندهندهی یک عنصر رابط کاربری است که روی دستگاه قابل مشاهده است. -
BySelector: معیارهایی را برای تطبیق عناصر رابط کاربری مشخص میکند. -
By:BySelectorرا به صورت مختصر و مفید میسازد. -
Configurator: به شما امکان میدهد پارامترهای کلیدی را برای اجرای تستهای UI Automator تنظیم کنید.
برای مثال، کد زیر نشان میدهد که چگونه میتوانید یک اسکریپت آزمایشی بنویسید که یک برنامه 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 Automator، مطمئن شوید که مکان کد منبع تست و وابستگیهای پروژه خود را پیکربندی کردهاید، همانطور که در بخش «تنظیم پروژه برای تست 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 Automator شما میتوانند به این اجزا دسترسی داشته باشند، بررسی کنید که این اجزا دارای برچسبهای متنی قابل مشاهده، مقادیر android:contentDescription یا هر دو باشند.
ابزار uiautomatorviewer یک رابط بصری مناسب برای بررسی سلسله مراتب طرحبندی و مشاهده ویژگیهای اجزای رابط کاربری که در پیشزمینه دستگاه قابل مشاهده هستند، فراهم میکند. این اطلاعات به شما امکان میدهد با استفاده از UI Automator تستهای دقیقتری ایجاد کنید. به عنوان مثال، میتوانید یک انتخابگر رابط کاربری ایجاد کنید که با یک ویژگی قابل مشاهده خاص مطابقت داشته باشد.
برای اجرای ابزار uiautomatorviewer :
- برنامه هدف را روی یک دستگاه فیزیکی اجرا کنید.
- دستگاه را به دستگاه توسعه خود وصل کنید.
- یک پنجره ترمینال باز کنید و به دایرکتوری
<android-sdk>/tools/بروید. - ابزار را با این دستور اجرا کنید:
$ uiautomatorviewer
برای مشاهده ویژگیهای رابط کاربری (UI) برنامه خود:
- در رابط کاربری
uiautomatorviewer، روی دکمهی «تصویر دستگاه» (Device Screenshot ) کلیک کنید. - برای مشاهدهی اجزای رابط کاربری شناساییشده توسط ابزار
uiautomatorviewer، نشانگر ماوس را روی تصویر لحظهای در پنل سمت چپ نگه دارید. ویژگیها در پنل سمت راست پایین و سلسله مراتب طرحبندی در پنل سمت راست بالا فهرست شدهاند. - در صورت تمایل، روی دکمهی Toggle NAF Nodes کلیک کنید تا اجزای رابط کاربری که برای UI Automator قابل دسترسی نیستند را مشاهده کنید. ممکن است فقط اطلاعات محدودی برای این اجزا در دسترس باشد.
برای آشنایی با انواع رایج اجزای رابط کاربری ارائه شده توسط اندروید، به رابط کاربری مراجعه کنید.
اطمینان حاصل کنید که فعالیت شما قابل دسترسی است
چارچوب تست UI Automator در برنامههایی که ویژگیهای دسترسیپذیری اندروید را پیادهسازی کردهاند، عملکرد بهتری دارد. وقتی از عناصر رابط کاربری از نوع View یا یک زیرکلاس View از SDK استفاده میکنید، نیازی به پیادهسازی پشتیبانی از دسترسیپذیری ندارید، زیرا این کلاسها قبلاً این کار را برای شما انجام دادهاند.
با این حال، برخی از برنامهها از عناصر رابط کاربری سفارشی برای ارائه یک تجربه کاربری غنیتر استفاده میکنند. چنین عناصری پشتیبانی خودکار از قابلیت دسترسی را ارائه نمیدهند. اگر برنامه شما شامل نمونههایی از یک زیرکلاس View است که از SDK نیست، با انجام مراحل زیر مطمئن شوید که ویژگیهای قابلیت دسترسی را به این عناصر اضافه میکنید:
- یک کلاس عینی ایجاد کنید که از ExploreByTouchHelper ارثبری کند.
- با فراخوانی تابع ()setAccessibilityDelegate، یک نمونه از کلاس جدید خود را به یک عنصر رابط کاربری سفارشی خاص مرتبط کنید.
برای راهنمایی بیشتر در مورد افزودن ویژگیهای دسترسی به عناصر نمای سفارشی، به «ساخت نماهای سفارشی قابل دسترس» مراجعه کنید. برای کسب اطلاعات بیشتر در مورد بهترین شیوههای کلی برای دسترسی در اندروید، به «دسترسپذیرتر کردن برنامهها» مراجعه کنید.
یک کلاس تست UI Automator ایجاد کنید
کلاس تست UI Automator شما باید به همان روش یک کلاس تست JUnit 4 نوشته شود. برای کسب اطلاعات بیشتر در مورد ایجاد کلاسهای تست JUnit 4 و استفاده از assertionها و annotationهای JUnit 4، به بخش «ایجاد یک کلاس تست واحد ابزار دقیق » مراجعه کنید.
حاشیهنویسی @RunWith(AndroidJUnit4.class) را در ابتدای تعریف کلاس تست خود اضافه کنید. همچنین باید کلاس AndroidJUnitRunner را که در AndroidX Test ارائه شده است، به عنوان اجراکننده تست پیشفرض خود مشخص کنید. این مرحله با جزئیات بیشتر در Run UI Automator tests on a device or emulator توضیح داده شده است.
مدل برنامهنویسی زیر را در کلاس تست UI Automator خود پیادهسازی کنید:
- با فراخوانی متد getInstance() و ارسال یک شیء Instrumentation به عنوان آرگومان، یک شیء
UiDeviceبرای دسترسی به دستگاهی که میخواهید آزمایش کنید، دریافت کنید. - با فراخوانی متد findObject() ، یک شیء
UiObject2را برای دسترسی به یک کامپوننت رابط کاربری که روی دستگاه نمایش داده میشود (مثلاً نمای فعلی در پیشزمینه) دریافت کنید. - با فراخوانی یک متد
UiObject2، یک تعامل کاربری خاص را برای انجام روی آن مولفه رابط کاربری شبیهسازی کنید؛ برای مثال، برای پیمایش، scrollUntil() و برای ویرایش یک فیلد متنی، setText() را فراخوانی کنید. میتوانید در صورت لزوم، APIهای مراحل ۲ و ۳ را مکرراً فراخوانی کنید تا تعاملات کاربری پیچیدهتری را که شامل چندین مولفه رابط کاربری یا توالی اقدامات کاربر هستند، آزمایش کنید. - بررسی کنید که رابط کاربری، پس از انجام این تعاملات با کاربر، منعکس کننده حالت یا رفتار مورد انتظار باشد.
این مراحل با جزئیات بیشتر در بخشهای زیر پوشش داده شدهاند.
دسترسی به اجزای رابط کاربری
شیء UiDevice روش اصلی دسترسی و دستکاری وضعیت دستگاه است. در تستهای خود، میتوانید متدهای UiDevice را برای بررسی وضعیت ویژگیهای مختلف، مانند جهت فعلی یا اندازه صفحه نمایش، فراخوانی کنید. تست شما میتواند از شیء UiDevice برای انجام اقدامات در سطح دستگاه، مانند وادار کردن دستگاه به چرخش خاص، فشار دادن دکمههای سختافزاری D-pad و فشار دادن دکمههای Home و Menu استفاده کند.
بهتر است تست خود را از صفحه اصلی دستگاه شروع کنید. از صفحه اصلی (یا هر مکان شروع دیگری که در دستگاه انتخاب کردهاید)، میتوانید متدهای ارائه شده توسط API UI Automator را برای انتخاب و تعامل با عناصر خاص رابط کاربری فراخوانی کنید.
قطعه کد زیر نشان میدهد که چگونه تست شما ممکن است یک نمونه از UiDevice را دریافت کرده و فشردن دکمه Home را شبیهسازی کند:
کاتلین
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) کمک میکند تا اطمینان حاصل شود که تستها فقط روی دستگاههایی با اندروید ۴.۳ (سطح API 18) یا بالاتر، مطابق با الزامات چارچوب UI Automator، اجرا میشوند.
از متد findObject() برای بازیابی یک UiObject2 استفاده کنید که نشاندهندهی نمایی است که با یک معیار انتخابگر مشخص مطابقت دارد. میتوانید در صورت نیاز، از نمونههای UiObject2 که ایجاد کردهاید، در سایر بخشهای تست برنامه خود استفاده مجدد کنید. توجه داشته باشید که چارچوب تست UI Automator هر بار که تست شما از یک نمونه UiObject2 برای کلیک روی یک عنصر UI یا پرس و جو از یک ویژگی استفاده میکند، نمایشگر فعلی را برای یافتن یک مورد منطبق جستجو میکند.
قطعه کد زیر نشان میدهد که چگونه تست شما ممکن است نمونههایی از UiObject2 بسازد که نشاندهندهی یک دکمهی لغو (Cancel) و یک دکمهی تأیید (OK) در یک برنامه باشند.
کاتلین
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();
}
یک انتخابگر مشخص کنید
اگر میخواهید به یک کامپوننت رابط کاربری خاص در یک برنامه دسترسی داشته باشید، از کلاس By برای ساخت یک نمونه BySelector استفاده کنید. BySelector یک کوئری برای عناصر خاص در رابط کاربری نمایش داده شده ارائه میدهد.
اگر بیش از یک عنصر منطبق پیدا شود، اولین عنصر منطبق در سلسله مراتب طرحبندی به عنوان هدف UiObject2 بازگردانده میشود. هنگام ساخت یک BySelector ، میتوانید چندین ویژگی را برای اصلاح جستجوی خود به هم پیوند دهید. اگر هیچ عنصر UI منطبقی پیدا نشود، مقدار null بازگردانده میشود.
شما میتوانید از متد hasChild() یا hasDescendant() برای تو در تو کردن چندین نمونه BySelector استفاده کنید. برای مثال، کد زیر نشان میدهد که چگونه تست شما ممکن است جستجویی را برای یافتن اولین ListView که دارای یک عنصر رابط کاربری فرزند با ویژگی 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 را دریافت کرد، میتوانید متدهای موجود در کلاس UiObject2 را برای انجام تعاملات کاربر روی کامپوننت رابط کاربری که توسط آن شیء نمایش داده میشود، فراخوانی کنید. میتوانید اقداماتی مانند موارد زیر را مشخص کنید:
-
click(): روی مرکز مرزهای قابل مشاهده عنصر رابط کاربری کلیک میکند. -
drag(): این شیء را به مختصات دلخواه میکشد. -
setText(): متن موجود در یک فیلد قابل ویرایش را پس از پاک کردن محتوای آن فیلد، تنظیم میکند. برعکس، متدclear()متن موجود در یک فیلد قابل ویرایش را پاک میکند. -
swipe(): عمل کشیدن انگشت به سمت جهت مشخص شده را انجام میدهد. -
scrollUntil(): عمل اسکرول را به سمت جهت مشخص شده انجام میدهد تا زمانی کهConditionیاEventConditionبرقرار شود.
چارچوب تست UI Automator به شما امکان میدهد بدون استفاده از دستورات shell، با دریافت یک شیء Context از طریق getContext() یک 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 ارثبری میکند، بنابراین میتوانید از متدهای استاندارد 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 Automator روی دستگاه یا شبیهساز
شما میتوانید تستهای UI Automator را از اندروید استودیو یا از طریق خط فرمان اجرا کنید. مطمئن شوید که AndroidJUnitRunner به عنوان اجراکننده پیشفرض instrumentation در پروژه خود مشخص کردهاید.
مثالهای بیشتر
تعامل با رابط کاربری سیستم
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 روشهای متعددی برای این کار ارائه میدهد:
-
UiDevice.performActionAndWait(Runnable action, EventCondition<U> condition, long timeout): برای مثال، برای کلیک روی یک دکمه و منتظر ماندن تا ظاهر شدن یک پنجره جدید،device.performActionAndWait(() -> button.click(), Until.newWindow(), timeout)را فراخوانی کنید. -
UiDevice.wait(Condition<Object, U> condition, long timeout): برای مثال، برای منتظر ماندن تا زمانی که یکUiObject2خاص روی دستگاه وجود داشته باشد،device.wait(Until.hasObject(By.text("my_text")), timeout);را فراخوانی کنید. -
UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout): برای مثال، برای صبر کردن تا تیک خوردن یک چکباکس،checkbox.wait(Until.checked(true), timeout);را فراخوانی کنید. -
UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout): برای مثال، برای کلیک روی یک دکمه و منتظر ماندن تا ظاهر شدن یک پنجره جدید، دستورbutton.clickAndWait(Until.newWindow(), timeout);را فراخوانی کنید. -
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull Condition<Object, U> condition): برای مثال، برای اسکرول کردن به پایین تا زمانی که یک شیء جدید ظاهر شود،object.scrollUntil(Direction.DOWN, Until.hasObject(By.text('new_obj'))); -
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull EventCondition<U> condition): برای مثال، برای اسکرول به پایین،object.scrollUntil(Direction.DOWN, Until.scrollFinished(Direction.DOWN));
قطعه کد زیر نحوه استفاده از 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 در تستهای اندروید، به منابع زیر مراجعه کنید.
مستندات مرجع:
نمونهها
- نمونه اولیه : نمونه اولیه خودکارساز رابط کاربری.