UI Automator to platforma do testowania interfejsu, która nadaje się do funkcjonalnego testowania interfejsu w różnych aplikacjach, w tym w aplikacjach systemowych i zainstalowanych. Interfejsy API UI Automator umożliwiają interakcję
z widocznymi elementami na urządzeniu niezależnie od tego, która Activity jest aktywna
. Dzięki temu możesz wykonywać takie operacje jak otwieranie menu Ustawienia
czy uruchamianie aplikacji na urządzeniu testowym. Test może wyszukiwać komponent interfejsu za pomocą wygodnych opisów, takich jak tekst wyświetlany w tym komponencie lub jego opis treści.
Platforma testowa UI Automator to interfejs API oparty na instrumentacji, który współpracuje
z AndroidJUnitRunner mechanizmem uruchamiania testów. Dobrze nadaje się do pisania automatycznych testów w stylu czarnej skrzynki, w których kod testowy nie zależy od wewnętrznych szczegółów implementacji aplikacji docelowej.
Główne funkcje platformy testowej UI Automator:
- Interfejs API do pobierania informacji o stanie i wykonywania operacji na urządzeniu docelowym. Więcej informacji znajdziesz w artykule Dostęp do stanu urządzenia.
- Interfejsy API, które obsługują testowanie interfejsu w różnych aplikacjach. Więcej informacji znajdziesz w artykule Interfejsy API UI Automator.
Dostęp do stanu urządzenia
Platforma testowa UI Automator udostępnia klasę UiDevice, która umożliwia dostęp do urządzenia, na którym działa aplikacja docelowa, i wykonywanie na nim operacji. Możesz wywoływać jej metody, aby uzyskiwać dostęp do właściwości urządzenia, takich jak bieżąca orientacja czy rozmiar ekranu. Klasa UiDevice umożliwia też wykonywanie tych działań:
- Zmiana orientacji urządzenia.
- Naciskanie przycisków sprzętowych, np. „przycisk zwiększania głośności”.
- Naciskanie przycisków Wstecz, Strona główna lub Menu.
- Otwieranie obszaru powiadomień.
- Robienie zrzutu ekranu bieżącego okna.
Aby na przykład zasymulować naciśnięcie przycisku Strona główna, wywołaj metodę UiDevice.pressHome().
Interfejsy API UI Automator
Interfejsy API UI Automator umożliwiają pisanie niezawodnych testów bez konieczności poznawania szczegółów implementacji aplikacji docelowej. Za pomocą tych interfejsów API możesz przechwytywać komponenty interfejsu i nimi manipulować w różnych aplikacjach:
UiObject2: reprezentuje element interfejsu widoczny na urządzeniu.BySelector: określa kryteria dopasowywania elementów interfejsu.By: tworzyBySelectorw zwięzły sposób.Configurator: umożliwia ustawianie kluczowych parametrów do uruchamiania testów UI Automator.
Na przykład ten kod pokazuje, jak napisać scenariusz testowania, który otwiera aplikację Gmail na urządzeniu:
Kotlin
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()
Java
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);
Konfigurowanie UI Automator
Zanim utworzysz test interfejsu za pomocą UI Automator, skonfiguruj lokalizację kodu źródłowego testu i zależności projektu zgodnie z opisem w artykule Konfigurowanie projektu na potrzeby AndroidX Test.
W pliku build.gradle modułu aplikacji na Androida musisz ustawić odwołanie do zależności z biblioteką UI Automator:
Kotlin
dependencies {
...
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
}
Dynamiczny
dependencies {
...
androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0"
}
Aby zoptymalizować testowanie za pomocą UI Automator, najpierw sprawdź komponenty interfejsu aplikacji docelowej i upewnij się, że są one dostępne. Te wskazówki dotyczące optymalizacji znajdziesz w 2 kolejnych sekcjach.
Sprawdzanie interfejsu na urządzeniu
Zanim zaprojektujesz test, sprawdź komponenty interfejsu widoczne na urządzeniu. Aby mieć pewność, że testy UI Automator będą mogły uzyskać dostęp do tych komponentów,
sprawdź, czy mają one widoczne etykiety tekstowe,
android:contentDescription wartości lub obie te rzeczy.
Narzędzie uiautomatorviewer udostępnia wygodny interfejs wizualny do sprawdzania hierarchii układu i wyświetlania właściwości komponentów interfejsu widocznych na pierwszym planie urządzenia. Te informacje umożliwiają tworzenie bardziej szczegółowych testów za pomocą UI Automator. Możesz na przykład utworzyć selektor interfejsu, który pasuje do określonej widocznej właściwości.
Aby uruchomić narzędzie uiautomatorviewer:
- Uruchom aplikację docelową na urządzeniu fizycznym.
- Podłącz urządzenie do komputera używanego do programowania.
- Otwórz okno terminala i przejdź do katalogu
<android-sdk>/tools/. - Uruchom narzędzie za pomocą tego polecenia:
$ uiautomatorviewer
Aby wyświetlić właściwości interfejsu aplikacji:
- W interfejsie
uiautomatorviewerkliknij przycisk Zrzut ekranu urządzenia. - Najedź kursorem na zrzut w panelu po lewej stronie, aby zobaczyć komponenty interfejsu zidentyfikowane przez narzędzie
uiautomatorviewer. Właściwości są wymienione w prawym dolnym panelu, a hierarchia układu – w prawym górnym panelu. - Opcjonalnie kliknij przycisk Przełącz węzły NAF , aby zobaczyć komponenty interfejsu, które są niedostępne dla UI Automator. W przypadku tych komponentów mogą być dostępne tylko ograniczone informacje.
Aby dowiedzieć się więcej o typowych typach komponentów interfejsu udostępnianych przez Androida, przeczytaj artykuł Interfejs użytkownika.
Sprawdzanie, czy aktywność jest dostępna
Platforma testowa UI Automator działa lepiej w przypadku aplikacji, które zaimplementowały funkcje ułatwień dostępu na Androida. Gdy używasz elementów interfejsu typu View lub
podklasy View z pakietu SDK, nie musisz implementować obsługi ułatwień dostępu
, ponieważ te klasy już to zrobiły.
Niektóre aplikacje używają jednak niestandardowych elementów interfejsu, aby zapewnić lepsze wrażenia użytkownika.
Takie elementy nie będą automatycznie obsługiwać ułatwień dostępu. Jeśli Twoja aplikacja zawiera instancje podklasy View, która nie pochodzi z pakietu SDK, dodaj do tych elementów funkcje ułatwień dostępu, wykonując te czynności:
- Utwórz konkretną klasę, która rozszerza ExploreByTouchHelper.
- Powiąż instancję nowej klasy z konkretnym niestandardowym elementem interfejsu, wywołując setAccessibilityDelegate().
Dodatkowe wskazówki dotyczące dodawania funkcji ułatwień dostępu do niestandardowych elementów widoku znajdziesz w artykule Tworzenie niestandardowych widoków z ułatwieniami dostępu. Więcej informacji o ogólnych sprawdzonych metodach dotyczących ułatwień dostępu na Androidzie znajdziesz w artykule Zwiększanie dostępności aplikacji.
Tworzenie klasy testowej UI Automator
Klasa testowa UI Automator powinna być napisana w taki sam sposób jak klasa testowa JUnit 4. Więcej informacji o tworzeniu klas testowych JUnit 4 oraz używaniu asercji i adnotacji JUnit 4 znajdziesz w artykule Tworzenie klasy testu jednostkowego z instrumentacją.
Na początku definicji klasy testowej dodaj adnotację @RunWith(AndroidJUnit4.class). Musisz też określić klasę AndroidJUnitRunner, która jest dostępna w AndroidX Test, jako domyślny mechanizm uruchamiania testów. Ten krok jest opisany bardziej szczegółowo w artykule Uruchamianie testów UI Automator na urządzeniu lub emulatorze.
W klasie testowej UI Automator zaimplementuj ten model programowania:
- Aby uzyskać dostęp do urządzenia, które chcesz przetestować, wywołaj
metodę getInstance() i przekaż jej jako argument obiekt Instrumentation.
UiDevice - Aby uzyskać dostęp do komponentu interfejsu wyświetlanego na
urządzeniu (np. bieżącego widoku na pierwszym planie), wywołaj metodę
findObject().
UiObject2 - Zasymuluj konkretną interakcję użytkownika, która ma być wykonana na tym komponencie interfejsu, wywołując metodę
UiObject2. Na przykład wywołaj scrollUntil(), aby przewijać, i setText(), aby edytować pole tekstowe. W razie potrzeby możesz wielokrotnie wywoływać interfejsy API w krokach 2 i 3, aby testować bardziej złożone interakcje użytkownika, które obejmują wiele komponentów interfejsu lub sekwencji działań użytkownika. - Sprawdź, czy interfejs odzwierciedla oczekiwany stan lub zachowanie po wykonaniu tych interakcji użytkownika.
Te kroki są bardziej szczegółowo opisane w sekcjach poniżej.
Dostęp do komponentów interfejsu
Obiekt UiDevice to podstawowy sposób uzyskiwania dostępu do
stanu urządzenia i manipulowania nim. W testach możesz wywoływać metody UiDevice, aby sprawdzać stan różnych właściwości, takich jak bieżąca orientacja czy rozmiar ekranu.
Test może używać obiektu UiDevice do wykonywania działań na poziomie urządzenia, takich jak wymuszanie określonej orientacji urządzenia, naciskanie przycisków sprzętowych padu kierunkowego oraz naciskanie przycisków Strona główna i Menu.
Dobrym rozwiązaniem jest rozpoczęcie testu od ekranu głównego urządzenia. Na ekranie głównym (lub w innej wybranej lokalizacji początkowej na urządzeniu) możesz wywoływać metody udostępniane przez interfejs UI Automator API, aby wybierać konkretne elementy interfejsu i wchodzić z nimi w interakcję.
Ten fragment kodu pokazuje, jak test może uzyskać instancję UiDevice i zasymulować naciśnięcie przycisku Strona główna:
Kotlin
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
)
}
}
Java
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);
}
}
W tym przykładzie instrukcja @SdkSuppress(minSdkVersion = 18) pomaga zapewnić, że testy będą uruchamiane tylko na urządzeniach z Androidem 4.3 (poziom 18 interfejsu API) lub nowszym, zgodnie z wymaganiami platformy UI Automator.
Użyj metody findObject(), aby pobrać UiObject2, który reprezentuje widok pasujący do podanych kryteriów selektora. W razie potrzeby możesz ponownie używać instancji UiObject2 utworzonych w innych częściach testowania aplikacji.
Pamiętaj, że platforma testowa UI Automator przeszukuje bieżący ekran w poszukiwaniu dopasowania za każdym razem, gdy test używa instancji UiObject2, aby kliknąć element interfejsu lub wysłać zapytanie o właściwość.
Ten fragment kodu pokazuje, jak test może tworzyć instancje UiObject2, które reprezentują przycisk Anuluj i przycisk OK w aplikacji.
Kotlin
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()
}
Java
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();
}
Określanie selektora
Jeśli chcesz uzyskać dostęp do konkretnego komponentu interfejsu w aplikacji, użyj klasy
By, aby utworzyć instancję BySelector. BySelector
reprezentuje zapytanie o konkretne elementy w wyświetlanym interfejsie.
Jeśli zostanie znaleziony więcej niż 1 pasujący element, jako docelowy UiObject2 zostanie zwrócony pierwszy pasujący element w hierarchii układu. Podczas tworzenia BySelector możesz łączyć ze sobą wiele właściwości, aby zawęzić wyszukiwanie. Jeśli nie zostanie znaleziony żaden pasujący element interfejsu, zostanie zwrócona wartość null.
Możesz użyć metody hasChild() lub hasDescendant(), aby zagnieżdżać
wiele instancji BySelector. Na przykład ten fragment kodu pokazuje
jak test może określić wyszukiwanie, aby znaleźć pierwszy ListView który
ma podrzędny element interfejsu z właściwością tekstową.
Kotlin
val listView: UiObject2 = device.findObject(
By.clazz("android.widget.ListView")
.hasChild(
By.text("Apps")
)
)
Java
UiObject2 listView = device.findObject(
By.clazz("android.widget.ListView")
.hasChild(
By.text("Apps")
)
);
W kryteriach selektora warto określić stan obiektu. Jeśli
na przykład chcesz wybrać listę wszystkich zaznaczonych elementów, aby je
wyczyścić, wywołaj metodę checked() z argumentem ustawionym na true.
Wykonywanie działań
Gdy test uzyska obiekt UiObject2, możesz wywoływać metody w klasie UiObject2, aby wykonywać interakcje użytkownika na komponencie interfejsu reprezentowanym przez ten obiekt. Możesz określić takie działania jak:
click(): klika środek widocznych granic elementu interfejsu.drag(): przeciąga ten obiekt do dowolnych współrzędnych.setText(): ustawia tekst w edytowalnym polu po wyczyszczeniu jego zawartości. Z kolei metodaclear()czyści istniejący tekst w edytowalnym polu.swipe(): wykonuje działanie przesuwania w określonym kierunku.scrollUntil(): wykonuje działanie przewijania w określonym kierunku dopóki nie zostanie spełniony warunekConditionlubEventCondition.
Platforma testowa UI Automator umożliwia wysyłanie intencji lub uruchamianie
aktywności bez używania poleceń powłoki. Wystarczy, że uzyskasz obiekt Context
za pomocą getContext().
Ten fragment kodu pokazuje, jak test może użyć intencji do uruchomienia testowanej aplikacji. To podejście jest przydatne, gdy interesuje Cię tylko testowanie aplikacji kalkulatora i nie zależy Ci na programie uruchamiającym.
Kotlin
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)
}
Java
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);
}
Weryfikowanie wyników
InstrumentationTestCase rozszerza TestCase, więc możesz używać standardowych metod JUnit Assert, aby sprawdzać, czy komponenty interfejsu w aplikacji zwracają oczekiwane wyniki.
Ten fragment kodu pokazuje, jak test może znaleźć kilka przycisków w aplikacji kalkulatora, kliknąć je w odpowiedniej kolejności, a następnie sprawdzić, czy wyświetla się prawidłowy wynik.
Kotlin
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)
}
Java
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());
}
Uruchamianie testów UI Automator na urządzeniu lub emulatorze
Testy UI Automator możesz uruchamiać w Android Studio lub w
wierszu poleceń. Upewnij się, że w projekcie jako domyślny mechanizm uruchamiania instrumentacji został określony AndroidJUnitRunner.
Więcej przykładów
Korzystanie z interfejsu systemu
UI Automator może wchodzić w interakcję ze wszystkim na ekranie, w tym z elementami systemu spoza aplikacji, jak pokazują te fragmenty kodu:
Kotlin
// Opens the System Settings. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.executeShellCommand("am start -a android.settings.SETTINGS")
Java
// Opens the System Settings. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.executeShellCommand("am start -a android.settings.SETTINGS");
Kotlin
// Opens the notification shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.openNotification()
Java
// Opens the notification shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.openNotification();
Kotlin
// Opens the Quick Settings shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.openQuickSettings()
Java
// Opens the Quick Settings shade. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.openQuickSettings();
Kotlin
// Get the system clock. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock")) print(clock.getText())
Java
// Get the system clock. device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock")); print(clock.getText());
Czekanie na przejścia
Przejścia między ekranami mogą trwać długo, a przewidywanie ich czasu trwania jest zawodne, dlatego po wykonaniu operacji należy poczekać na UI Automator. UI Automator udostępnia do tego kilka metod:
UiDevice.performActionAndWait(Runnable action, EventCondition<U> condition, long timeout): aby na przykład kliknąć przycisk i poczekać, aż pojawi się nowe okno, wywołajdevice.performActionAndWait(() -> button.click(), Until.newWindow(), timeout).UiDevice.wait(Condition<Object, U> condition, long timeout): aby na przykład poczekać, aż na urządzeniu pojawi się określonyUiObject2, wywołajdevice.wait(Until.hasObject(By.text("my_text")), timeout);UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout): aby na przykład poczekać, aż pole wyboru zostanie zaznaczone, wywołajcheckbox.wait(Until.checked(true), timeout);UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout): aby na przykład kliknąć przycisk i poczekać, aż pojawi się nowe okno, wywołajbutton.clickAndWait(Until.newWindow(), timeout);UiObject2.scrollUntil(@NonNull Direction direction, @NonNull Condition<Object, U> condition): aby na przykład przewinąć w dół, aż pojawi się nowy obiekt, wywołajobject.scrollUntil(Direction.DOWN, Until.hasObject(By.text('new_obj')));.UiObject2.scrollUntil(@NonNull Direction direction, @NonNull EventCondition<U> condition): aby na przykład przewinąć w dół do końca, wywołajobject.scrollUntil(Direction.DOWN, Until.scrollFinished(Direction.DOWN));
Ten fragment kodu pokazuje, jak za pomocą UI Automator wyłączyć tryb Nie przeszkadzać w ustawieniach systemu za pomocą metody performActionAndWait(), która czeka na przejścia:
Kotlin
@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)) }
Java
@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)); }
Dodatkowe materiały
Więcej informacji o używaniu UI Automator w testach na Androida znajdziesz w tych materiałach.
Dokumentacja źródłowa:
Przykłady
- BasicSample: podstawowy przykład UI Automator.