Automator UI to platforma do testowania interfejsu użytkownika, która umożliwia testowanie funkcjonalności interfejsu w różnych aplikacjach w systemie i zainstalowanych aplikacjach. Interfejsy automatyzacji interfejsu użytkownika umożliwiają interakcję z widocznymi elementami na urządzeniu niezależnie od tego, który Activity
jest w centrum uwagi. Dzięki temu można wykonywać na urządzeniu testowym takie operacje jak otwieranie menu Ustawienia lub menu aplikacji. Test może wyszukiwać element UI, korzystając z wygodnych deskryptorów, takich jak tekst wyświetlany w tym elemencie lub opis treści.
Platforma testowania UI Automator to interfejs API oparty na instrumentacji, który współpracuje z narzędziem do testowania AndroidJUnitRunner
. Jest ona odpowiednia do pisania testów automatycznych typu „czarna skrzynka”, w których kod testowy nie zależy od wewnętrznych szczegółów implementacji aplikacji docelowej.
Najważniejsze funkcje platformy testowania Automator interfejsu użytkownika to:
- Interfejs API do pobierania informacji o stanie i wykonywania operacji na urządzeniu docelowym. Więcej informacji znajdziesz w artykule Uzyskiwanie dostępu do stanu urządzenia.
- Interfejsy API obsługujące testowanie interfejsu użytkownika w wielu aplikacjach. Więcej informacji znajdziesz w artykule UIAutomator APIs.
Dostęp do stanu urządzenia
Platforma testowania UI Automator udostępnia klasę UiDevice
, która umożliwia dostęp do urządzenia, na którym działa aplikacja docelowa, oraz wykonywanie na nim operacji. Możesz wywoływać jego metody, aby uzyskać dostęp do właściwości urządzenia, takich jak bieżąca orientacja lub rozmiar wyświetlacza. Klasa UiDevice
umożliwia też wykonywanie tych działań:
- Zmień orientację urządzenia.
- nacisnąć przyciski sprzętowe, takie jak „zwiększ głośność”.
- Naciśnij przycisk Wstecz, przycisk ekranu głównego lub przycisk Menu.
- Otwórz obszar powiadomień.
- Zrób zrzut bieżącego okna.
Na przykład aby zasymulować naciśnięcie przycisku ekranu głównego, wywołaj metodę UiDevice.pressHome()
.
Interfejsy API Automator UI
Interfejsy API UI Automator umożliwiają tworzenie niezawodnych testów bez konieczności znajomości szczegółów implementacji aplikacji, na którą się kierujesz. Za pomocą tych interfejsów API możesz rejestrować i modyfikować komponenty interfejsu użytkownika w różnych aplikacjach:
UiObject2
: element interfejsu widoczny na urządzeniu.BySelector
: określa kryteria dopasowywania elementów interfejsu.By
: tworzyBySelector
w zwięzły sposób.Configurator
: umożliwia ustawienie kluczowych parametrów do przeprowadzania testów Automatora UI.
Na przykład kod poniżej pokazuje, jak napisać skrypt testowy, który otwiera aplikację Gmail na urządzeniu:
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);
Konfigurowanie automatyzacji interfejsu
Zanim utworzysz test UI za pomocą UI Automator, pamiętaj o skonfigurowaniu lokalizacji kodu źródłowego testu i zależności projektu zgodnie z opisem w artykule Konfigurowanie projektu na potrzeby testu AndroidX.
W pliku build.gradle
w module aplikacji na Androida musisz ustawić odwołanie do biblioteki UI Automator:
dependencies {
...
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
}
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0'
}
Aby zoptymalizować testowanie za pomocą UI Automator, najpierw sprawdź komponenty interfejsu użytkownika docelowej aplikacji i upewnij się, że są one dostępne. Wskazówki dotyczące optymalizacji znajdziesz w następnych 2 sekcjach.
Sprawdzanie interfejsu użytkownika na urządzeniu
Zanim zaczniesz projektować test, sprawdź komponenty interfejsu widoczne na urządzeniu. Aby mieć pewność, że testy Automatora UI mogą uzyskać dostęp do tych komponentów, sprawdź, czy mają one widoczne etykiety tekstowe, wartości android:contentDescription
lub jedno i drugie.
Narzędzie uiautomatorviewer
udostępnia wygodny interfejs wizualny, który pozwala sprawdzić hierarchię układu i właściwości komponentów interfejsu widocznych na pierwszym planie na urządzeniu. Dzięki tym informacjom możesz tworzyć bardziej szczegółowe testy za pomocą UI Automator. Możesz na przykład utworzyć selektor interfejsu użytkownika, który pasuje do konkretnej widocznej właściwości.
Aby uruchomić narzędzie uiautomatorviewer
:
- Uruchom aplikację docelową na urządzeniu fizycznym.
- Podłącz urządzenie do komputera deweloperskiego.
- 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 użytkownika aplikacji:
- W interfejsie
uiautomatorviewer
kliknij przycisk Zrzut ekranu urządzenia. - Najechać kursorem na zrzut ekranu w panelu po lewej stronie, aby wyświetlić elementy interfejsu zidentyfikowane przez narzędzie
uiautomatorviewer
. Właściwości są wymienione w panelu po prawej stronie, a hierarchia układu – w panelu po prawej stronie u góry. - Opcjonalnie kliknij przycisk Toggle NAF Nodes (Przełącz węzły NAF), aby wyświetlić komponenty interfejsu, do których UI Automator nie ma dostępu. W przypadku tych komponentów może być dostępna tylko ograniczona ilość informacji.
Więcej informacji o popularnych typach komponentów UI w Androidzie znajdziesz w artykule Interfejs użytkownika.
Zadbaj o dostępność swojej aktywności
Platforma testowa UI Automator działa lepiej w przypadku aplikacji, które mają zaimplementowane funkcje ułatwień dostępu na Androidzie. Jeśli używasz elementów interfejsu typu View
lub podklasy View
z pakietu SDK, nie musisz implementować obsługi funkcji ułatwień dostępu, ponieważ te klasy już to zrobiły.
Niektóre aplikacje korzystają jednak z niestandardowych elementów interfejsu, aby zapewnić większą wygodę użytkownikom.
Takie elementy nie będą obsługiwać automatycznego dostępu. Jeśli Twoja aplikacja zawiera instancje podklasy klasy 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ę rozszerzającą klasę ExploreByTouchHelper.
- Połącz instancję nowej klasy z konkretnym niestandardowym elementem interfejsu, wywołując metodę setAccessibilityDelegate().
Więcej wskazówek dotyczących dodawania funkcji ułatwień dostępu do elementów widoku niestandardowego znajdziesz w artykule Tworzenie widoków niestandardowych z ułatwieniami dostępu. Więcej informacji o ogólnych sprawdzonych metodach dotyczących ułatwień dostępu na Androidzie znajdziesz w artykule Ułatwianie dostępu do aplikacji.
Tworzenie klasy testu UI Automator
Klasa testu UI Automator powinna być napisana w taki sam sposób jak klasa testu JUnit 4. Więcej informacji o tworzeniu klas testów JUnit 4 i używaniu asercji oraz adnotacji JUnit 4 znajdziesz w artykule Tworzenie klasy testu jednostkowego z użyciem instrumentacji.
Dodaj adnotację @RunWith(AndroidJUnit4.class) na początku definicji klasy testowej. Musisz też wskazać jako domyślny mechanizm uruchamiania testów klasę AndroidJUnitRunner udostępnioną w AndroidX Test. Ten krok jest opisany bardziej szczegółowo w artykule Testowanie automatyzacji interfejsu użytkownika na urządzeniu lub w emulatorze.
W klasie testu UI Automator zastosuj ten model programowania:
- Aby uzyskać dostęp do urządzenia, które chcesz przetestować, pobierz obiekt
UiDevice
, wywołując metodę getInstance() i przekazując jako argument obiekt Instrumentation. - Aby uzyskać dostęp do elementu interfejsu wyświetlanego na urządzeniu (np. bieżący widok na pierwszym planie), pobierz obiekt
UiObject2
, wywołując metodę findObject(). - Symuluj określone interakcje użytkownika z tym komponentem UI, wywołując metodę
UiObject2
. Na przykład wywołaj metodę scrollUntil(), aby przewinąć, oraz setText(), aby edytować pole tekstowe. Aby przetestować bardziej złożone interakcje z użytkownikiem, które obejmują wiele elementów interfejsu użytkownika lub sekwencji działań użytkownika, możesz wielokrotnie wywoływać interfejsy API w kroku 2 i 3. - Sprawdź, czy interfejs reaguje zgodnie z oczekiwanym stanem lub zachowaniem po wykonaniu tych interakcji użytkownika.
Te czynności są opisane bardziej szczegółowo w sekcjach poniżej.
Dostęp do komponentów interfejsu
Obiekt UiDevice
to główny 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 lub rozmiar wyświetlacza.
Test może używać obiektu UiDevice
do wykonywania działań na poziomie urządzenia, takich jak wymuszanie określonego obracania urządzenia, naciskanie przycisków D-pad oraz przycisków Home i Menu.
Warto rozpocząć testowanie od ekranu głównego urządzenia. Na ekranie głównym (lub innym wybranym przez Ciebie miejscu na urządzeniu) możesz wywoływać metody udostępnione przez interfejs API automatyzacji interfejsu użytkownika, aby wybierać określone elementy interfejsu i z nimi wchodzić w interakcje.
Ten fragment kodu pokazuje, jak test może uzyskać instancję UiDevice
i zasymulować naciśnięcie przycisku Strona główna:
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); } }
W tym przykładzie instrukcja @SdkSuppress(minSdkVersion = 18) pomaga zapewnić, aby testy były uruchamiane tylko na urządzeniach z Androidem 4.3 (poziom interfejsu API 18) lub nowszym, zgodnie z wymaganiami platformy UI Automator.
Aby pobrać findObject()
, które reprezentuje widok zgodny z danymi kryteriami selektora, użyj metody findObject()
.UiObject2
W razie potrzeby możesz ponownie użyć instancji UiObject2
, które zostały utworzone w innych częściach testów aplikacji.
Pamiętaj, że platforma testów UI Automator wyszukuje dopasowanie w bieżącym wyświetleniu za każdym razem, gdy test używa instancji UiObject2
do kliknięcia elementu interfejsu lub zapytania właściwości.
Ten fragment kodu pokazuje, jak test może tworzyć instancje UiObject2
, które reprezentują w aplikacji przycisk Anuluj i 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(); }
Określanie selektora
Jeśli chcesz uzyskać dostęp do określonego komponentu UI w aplikacji, użyj klasy By
, aby utworzyć instancję BySelector
. BySelector
reprezentuje zapytanie o określone elementy w wyświetlanym interfejsie.
Jeśli zostanie znaleziony więcej niż 1 element pasujący do kryteriów, jako docelowe UiObject2
zwrócony zostanie pierwszy pasujący element w hierarchii układu. Podczas tworzenia zapytania BySelector
możesz połączyć ze sobą wiele usług, aby zawęzić zakres wyszukiwania. Jeśli nie zostanie znaleziony żaden pasujący element interfejsu użytkownika, zwrócona zostanie wartość null
.
Aby zagnieżdżać wiele wystąpień funkcji BySelector
, możesz użyć metody hasChild()
lub hasDescendant()
. Na przykład poniższy przykład kodu pokazuje, jak test może określić wyszukiwanie, aby znaleźć pierwszy element ListView
, który ma element podrzędny interfejsu użytkownika z właściwością tekstową.
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") ) );
W kryteriach selektora warto podać stan obiektu. Jeśli na przykład chcesz wybrać listę wszystkich zaznaczonych elementów, aby móc je odznaczyć, wywołaj metodę checked()
z argumentem ustawionym na wartość true.
Wykonywanie działań
Gdy test uzyska obiekt UiObject2
, możesz wywoływać metody klasy UiObject2
, aby przeprowadzać interakcje użytkownika z elementem UI reprezentowanym przez ten obiekt. Możesz określić takie działania jak:
click()
: kliknięcie środka widocznych granic elementu interfejsu.drag()
: przeciąganie tego obiektu do dowolnych współrzędnych.setText()
: ustawia tekst w polu tekstowym po wyczyszczeniu jego zawartości. Natomiast metodaclear()
czyści istniejący tekst w polu tekstowym z możliwością edycji.swipe()
: wykonuje działanie przesunięcia w określonym kierunku.scrollUntil()
: wykonuje działanie przewijania w określonym kierunku, aż do spełnienia warunkuCondition
lubEventCondition
.
Platforma testowania UI Automator umożliwia wysyłanie intencji lub uruchamianie działalności bez używania poleceń powłoki, a zamiast tego uzyskując obiekt Context za pomocą getContext()
.
Poniższy fragment kodu pokazuje, jak test może używać intencji do uruchamiania testowanej aplikacji. To podejście jest przydatne, gdy interesuje Cię tylko testowanie aplikacji kalkulatora, a nie launchera.
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); }
Weryfikowanie wyników
Klasa InstrumentationTestCase rozszerza klasę TestCase, dzięki czemu możesz używać standardowych metod JUnit Assert do testowania, czy komponenty UI w aplikacji zwracają oczekiwane wyniki.
Poniższy fragment kodu pokazuje, jak test może zlokalizować kilka przycisków w aplikacji kalkulatora, kliknąć je kolejno, a następnie sprawdzić, czy wyświetlany jest prawidłowy wynik.
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()); }
Uruchamianie testów UI Automator na urządzeniu lub emulatorze
Testy UI Automator możesz uruchamiać w Android Studio lub z poziomu wiersza poleceń. W projekcie ustaw AndroidJUnitRunner
jako domyślny program do wykonywania pomiarów.
Więcej przykładów
Interakcja z interfejsem systemu
UI Automator może wchodzić w interakcje ze wszystkim na ekranie, w tym z elementami systemu poza aplikacją, jak pokazano w tych fragmentach kodu:
// 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());
Czekaj na przejścia

Przechodzenie między ekranami może zająć trochę czasu, a przewidywanie czasu trwania tych operacji jest niewiarygodne. Dlatego po wykonaniu operacji należy ustawić w UI Automator opóźnienie. UI Automator oferuje 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łaj funkcjędevice.performActionAndWait(() -> button.click(), Until.newWindow(), timeout)
.UiDevice.wait(Condition<Object, U> condition, long timeout)
: na przykład, aby zaczekać, aż na urządzeniu pojawi się określonaUiObject2
, wywołaj funkcjędevice.wait(Until.hasObject(By.text("my_text")), timeout);
.UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout)
: aby na przykład zaczekać, aż pole wyboru zostanie zaznaczone, wywołaj funkcjęcheckbox.wait(Until.checked(true), timeout);
UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout)
: na przykład, aby kliknąć przycisk i poczekać, aż pojawi się nowe okno, wywołaj funkcjębutton.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łaj funkcjęobject.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ół, wywołaj funkcjęobject.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:
@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)); }
Dodatkowe materiały
Więcej informacji o używaniu UI Automator w testach na Androida znajdziesz w tych materiałach.
Dokumentacja:
Próbki
- BasicSample: podstawowy przykład automatyzacji interfejsu.