Automator UI to platforma do testowania UI odpowiednia do testowania funkcjonalnego interfejsu między aplikacjami w systemie i w aplikacjach zainstalowanych. Interfejsy API Automator pozwalają wchodzić w interakcje z widocznymi elementami na urządzeniu, niezależnie od tego, które z nich Activity
jest aktywne. Dzięki temu można wykonywać takie działania jak otwieranie menu Ustawienia czy uruchamianie aplikacji na urządzeniu testowym. W ramach testu można wyszukiwać element interfejsu za pomocą wygodnych deskryptorów, np. tekstu wyświetlanego w tym komponencie lub jego opisu treści.
Platforma testowania Automatyzatora UI to interfejs API oparty na narzędziach i współpracuje z uruchamiającym testem AndroidJUnitRunner
. Dobrze sprawdza się w przypadku nieprzezroczystych testów automatycznych, których kod testów nie zależy od wewnętrznych szczegółów implementacji aplikacji docelowej.
Najważniejsze funkcje środowiska testowego Automatyzatora UI to m.in.:
- Interfejs API do pobierania informacji o stanie i wykonywania operacji na urządzeniu docelowym. Więcej informacji znajdziesz w sekcji Uzyskiwanie dostępu do stanu urządzenia.
- Interfejsy API, które obsługują testowanie interfejsu między aplikacjami. Więcej informacji znajdziesz w artykule o interfejsach API Automator.
Dostęp do stanu urządzenia
Platforma testowania Automatyzatora UI 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 uzyskać dostęp do właściwości urządzenia, takich jak bieżąca orientacja czy rozmiar wyświetlacza. Klasa UiDevice
pozwala też wykonywać te działania:
- Zmień ustawienie obrotu urządzenia.
- Naciśnij klawisze sprzętowe, np. „zwiększ głośność”.
- Naciśnij przycisk Wstecz, Ekran główny lub Menu.
- Otwórz obszar powiadomień.
- Zrób zrzut ekranu bieżącego okna.
Aby np. symulować naciśnięcie przycisku ekranu głównego, wywołaj metodę UiDevice.pressHome()
.
Interfejsy API Automator
Interfejsy API Automatora umożliwiają pisanie rzetelnych testów bez znajomości szczegółów implementacji aplikacji, na którą kierujesz reklamy. Te interfejsy API pozwalają przechwytywać komponenty UI i manipulować nimi w wielu aplikacjach:
UiObject2
: reprezentuje element interfejsu widoczny na urządzeniu.BySelector
: określa kryteria dopasowania elementów interfejsu.By
: tworzyBySelector
w zwięzły sposób.Configurator
: pozwala ustawić kluczowe parametry do uruchamiania testów Automatyzatora UI.
Na przykład ten kod pokazuje, jak można napisać skrypt testowy, 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);
Skonfiguruj Automatyzatora UI
Zanim utworzysz test interfejsu użytkownika za pomocą Automatora interfejsu, skonfiguruj lokalizację kodu źródłowego i zależności projektu testowego zgodnie z opisem w sekcji Konfigurowanie projektu na potrzeby testu AndroidX.
W pliku build.gradle
modułu aplikacji na Androida ustaw odniesienie do zależności z biblioteką Automator interfejsu:
Kotlin
dependencies {
...
androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}
Odlotowy
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}
Aby zoptymalizować testowanie przez działanie Automatyzatora UI, najpierw sprawdź komponenty interfejsu aplikacji docelowej i upewnij się, że są dostępne. Te wskazówki optymalizacyjne opisaliśmy w 2 kolejnych sekcjach.
Sprawdzanie UI na urządzeniu
Przed zaprojektowaniem testu sprawdź komponenty UI widoczne na urządzeniu. Aby mieć pewność, że testy Automatyzatora interfejsu mają dostęp do tych komponentów, sprawdź, czy mają widoczne etykiety tekstowe, wartości android:contentDescription
lub oba te elementy.
Narzędzie uiautomatorviewer
to wygodny interfejs wizualny, który pozwala sprawdzić hierarchię układu i wyświetlić właściwości komponentów UI widocznych na pierwszym planie urządzenia. Te informacje pozwalają tworzyć bardziej szczegółowe testy za pomocą Automatora UI. Można np. utworzyć selektor interfejsu, który odpowiada określonej widocznej właściwości.
Aby uruchomić narzędzie uiautomatorviewer
:
- Uruchom docelową aplikację na urządzeniu fizycznym.
- Podłącz urządzenie do komputera 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
uiautomatorviewer
kliknij przycisk Zrzut ekranu urządzenia. - Najedź kursorem na zrzut w panelu po lewej stronie, aby wyświetlić komponenty interfejsu zidentyfikowane przez narzędzie
uiautomatorviewer
. Właściwości są wymienione w panelu w prawym dolnym rogu, a w hierarchii układu – w panelu w prawym górnym rogu. - Opcjonalnie kliknij przycisk Przełącz węzły NAF, aby wyświetlić komponenty UI niedostępne dla Automatora UI. W przypadku tych komponentów dostępne mogą być tylko niektóre informacje.
Informacje o typowych typach komponentów interfejsu dostępnych w Androidzie znajdziesz w artykule Interfejs użytkownika.
Upewnij się, że informacje o Twojej aktywności są dostępne
Platforma testowa Automator interfejsu działa lepiej w aplikacjach z zaimplementowanymi ułatwieniami dostępu na Androidzie. 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 zrobiły to już za Ciebie.
Niektóre aplikacje korzystają jednak z niestandardowych elementów interfejsu, by zwiększyć wygodę użytkowników.
Takie elementy nie zapewniają automatycznej obsługi ułatwień dostępu. Jeśli Twoja aplikacja zawiera wystąpienia podklasy View
, które nie pochodzą z pakietu SDK, dodaj do tych elementów ułatwienia dostępu, wykonując te czynności:
- Utwórz konkretne zajęcia, które rozszerzają zakres ExploreByTouchHelper.
- Powiąż instancję nowej klasy z określonym niestandardowym elementem interfejsu, wywołując funkcję setAccessibilityDelegate().
Dodatkowe wskazówki dotyczące dodawania ułatwień dostępu do elementów widoków niestandardowych znajdziesz w artykule o tworzeniu widoków niestandardowych z dostępem do ułatwień 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 Automator interfejsu
Klasa testowa Automator interfejsu użytkownika 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 instrumentowanej klasy testów jednostkowych.
Dodaj adnotację @RunWith(AndroidJUnit4.class) na początku definicji klasy testowej. Musisz też wskazać klasę AndroidJUnitRunner dostępną w narzędziu AndroidX Test jako domyślny system uruchamiający testy. Szczegółowo opisujemy ten krok w artykule Przeprowadzanie testów Automatora UI na urządzeniu lub w emulatorze.
Zaimplementuj ten model programowania w klasie testowej Automator interfejsu:
- Pobierz obiekt
UiDevice
, aby uzyskać dostęp do urządzenia, które chcesz przetestować. Aby to zrobić, wywołaj metodę getInstance() i przekaż go jako argument obiekt Instrumentation. - Pobierz obiekt
UiObject2
, aby uzyskać dostęp do komponentu interfejsu wyświetlanego na urządzeniu (np. bieżącego widoku na pierwszym planie) przez wywołanie metody findObject(). - Symulowanie konkretnej interakcji użytkownika z danym komponentem interfejsu przez wywołanie metody
UiObject2
. Może to być np. wywołanie scrollUntil() w celu przewijania lub setText(), które pozwala edytować pole tekstowe. Interfejsy API w krokach 2 i 3 możesz wywoływać wielokrotnie w razie potrzeby, aby przetestować bardziej złożone interakcje użytkownika, które obejmują wiele komponentów UI lub sekwencje działań użytkownika. - Po wykonaniu tych interakcji użytkowników sprawdź, czy interfejs przedstawia oczekiwany stan i sposób działania.
Szczegółowy opis tych czynności znajdziesz w poniższych sekcjach.
Dostęp do komponentów interfejsu
Obiekt UiDevice
to główny sposób uzyskiwania dostępu do stanu urządzenia i modyfikowania go. W testach możesz wywoływać metody UiDevice
, aby sprawdzić stan różnych właściwości, takich jak bieżąca orientacja czy rozmiar wyświetlacza.
Test może używać obiektu UiDevice
do wykonywania działań na poziomie urządzenia, takich jak wymuszanie wykonania określonego obrotu, naciśnięcie przycisków na padzie kierunkowym oraz przycisków ekranu głównego i menu.
Dobrą praktyką jest rozpoczynanie testu na ekranie głównym urządzenia. Na ekranie głównym (lub w innej lokalizacji początkowej wybranej na urządzeniu) możesz wywoływać metody udostępniane przez interfejs UI Automator API, aby wybierać elementy interfejsu i wchodzić z nimi w interakcje.
Ten fragment kodu pokazuje, jak w ramach testu można uzyskać wystąpienie UiDevice
i symulować naciśnięcie przycisku ekranu głównego:
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 przykładzie instrukcja @SdkSuppress(minSdkVersion = 18) pomaga zapewnić, że testy będą przeprowadzane tylko na urządzeniach z Androidem 4.3 (poziom interfejsu API 18) lub nowszym, zgodnie z wymaganiami platformy UI Automator.
Metoda findObject()
pozwala pobrać obiekt UiObject2
, który reprezentuje widok spełniający określone kryteria selektora. W razie potrzeby możesz ponownie używać instancji UiObject2
utworzonych przez siebie na innych etapach testowania aplikacji.
Pamiętaj, że platforma testowa Automatyzatora UI przeszukuje bieżący wyświetlacz pod kątem dopasowania za każdym razem, gdy w teście kliknięcie elementu interfejsu lub zapytania dotyczącego właściwości obejmuje wystąpienie UiObject2
.
Poniższy fragment kodu pokazuje, jak test może utworzyć instancje UiObject2
reprezentujące 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śl selektor
Jeśli chcesz uzyskać dostęp do określonego komponentu interfejsu w aplikacji, użyj klasy By
do utworzenia wystąpienia BySelector
. BySelector
reprezentuje zapytanie o konkretne elementy wyświetlanego interfejsu.
Jeśli zostanie znaleziony więcej niż 1 pasujący element, jako docelowy UiObject2
zwracany jest pierwszy pasujący element w hierarchii układu. Podczas tworzenia obiektu BySelector
możesz połączyć kilka właściwości, aby zawęzić wyszukiwanie. Jeśli nie znajdzie pasującego elementu interfejsu, zwracany jest element null
.
Aby zagnieździć wiele instancji BySelector
, możesz użyć metody hasChild()
lub hasDescendant()
. Na przykład ten przykładowy kod pokazuje, jak podczas testu można określić wyszukiwanie, aby znaleźć pierwszy element ListView
zawierający 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") ) );
Stan obiektu możesz określić w kryteriach selektora. Jeśli np. chcesz wybrać listę wszystkich zaznaczonych elementów, aby je odznaczyć, wywołaj metodę checked()
z argumentem ustawionym na „prawda”.
Wykonywanie działań
Gdy test uzyska obiekt UiObject2
, możesz wywołać metody w klasie UiObject2
, aby wykonywać interakcje użytkowników w reprezentowanym przez ten obiekt komponencie interfejsu użytkownika. Możesz określić, takie działania jak:
click()
: klika środek widocznych granic elementu interfejsu.drag()
: przeciąga obiekt do dowolnych współrzędnych.setText()
: umieszcza tekst w polu do edycji po wyczyszczeniu jego zawartości. I na odwrót: metodaclear()
czyści istniejący tekst w polu możliwym do edytowania.swipe()
: przesuwanie palcem w określonym kierunku.scrollUntil()
: wykonuje przewijanie w kierunku określonego kierunku, dopóki nie zostaną spełnione kryteriaCondition
lubEventCondition
.
Platforma testowa Automatora UI umożliwia wysyłanie intencji lub uruchamianie aktywności bez używania poleceń powłoki za pomocą pobierania obiektu Kontekst za pomocą getContext()
.
Ten fragment kodu pokazuje, jak podczas testu można użyć intencji do uruchomienia testowanej aplikacji. Ta metoda jest przydatna, gdy chcesz przetestować tylko aplikację Kalkulator i nie interesuje Cię program uruchamiający.
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); }
Sprawdź wyniki
Parametr InstrumentationTestCase rozszerza zakres TestCase, dzięki czemu możesz użyć standardowych metod JUnit Assert, aby przetestować, czy komponenty interfejsu użytkownika w aplikacji zwracają oczekiwane wyniki.
Ten fragment kodu pokazuje, jak podczas testu znaleźć kilka przycisków w aplikacji Kalkulator, klikać je po kolei i sprawdzać, czy wyświetlany jest 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()); }
Uruchamiaj testy Automatora UI na urządzeniu lub w emulatorze
Testy Automatora interfejsu możesz uruchamiać w Android Studio lub z poziomu wiersza poleceń. Pamiętaj, aby określić AndroidJUnitRunner
jako domyślną aplikację uruchamiającą instrument w projekcie.
Więcej przykładów
Interakcja z interfejsem systemu
Automator UI może wchodzić w interakcje ze wszystkim, co znajduje się na ekranie, w tym z elementami systemu poza aplikacją, jak pokazano w tych fragmentach 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());
Poczekaj na przeniesienie
![Wyłącz zakłócenia](https://developer.android.com/static/images/testing/uiautomator_turn_off_disturb.gif?authuser=6&hl=pl)
Przejścia ekranu mogą trochę potrwać, a przewidywanie ich czasu trwania jest mało miarodajne, dlatego Automator UI powinien czekać po wykonaniu operacji. Automator UI udostępnia wiele metod, które pozwalają to zrobić:
UiDevice.performActionAndWait(Runnable action, EventCondition<U> condition, long timeout)
: aby na przykład kliknąć przycisk i poczekać na wyświetlenie nowego okna, zadzwoń pod numerdevice.performActionAndWait(() -> button.click(), Until.newWindow(), timeout)
UiDevice.wait(Condition<Object, U> condition, long timeout)
: aby na przykład zaczekać, aż na urządzeniu zostanie ustawiony określony numerUiObject2
, zadzwoń pod numerdevice.wait(device.hasObject(By.text("my_text")), timeout);
UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout)
: na przykład aby czekać na zaznaczenie pola wyboru, wywołaj poleceniecheckbox.wait(Until.checked(true), timeout);
UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout)
: aby na przykład kliknąć przycisk i poczekać na wyświetlenie nowego okna, zadzwoń pod numerbutton.clickAndWait(Until.newWindow(), timeout);
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull Condition<Object, U> condition)
: aby na przykład przewinąć w dół i zobaczyć 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ąć na sam dół strony, wywołaj polecenieobject.scrollUntil(Direction.DOWN, Until.scrollFinished(Direction.DOWN));
Ten fragment kodu pokazuje, jak za pomocą narzędzia UI Automator wyłączyć tryb Nie przeszkadzać w ustawieniach systemu przy użyciu metody performActionAndWait()
, która oczekuje na przeniesienie:
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 korzystaniu z Automatora UI w testach Androida znajdziesz w tych materiałach.
Dokumentacja źródłowa:
Próbki
- BasicSample: przykład narzędzia Automator podstawowego interfejsu użytkownika.