Pisanie automatycznych testów za pomocą Automatora UI

UI Automator to platforma do testowania UI przeznaczona do działania z różnych aplikacji testowania w systemach i aplikacjach zainstalowanych. Interfejsy UI Automator API umożliwiają interakcje z widocznymi elementami na urządzeniu, niezależnie od tego, gdzie znajduje się Activity umożliwia wykonywanie operacji, takich jak otwarcie menu Ustawienia lub Menu z aplikacjami na urządzeniu testowym. Test może wyszukać komponent UI przez za pomocą wygodnych deskryptorów, takich jak tekst wyświetlany w danym komponencie lub jego opis treści.

Platforma testowa UI Automator to interfejs API oparty na instrumentacji, który działa za pomocą biegu testowego AndroidJUnitRunner. Idealnie nadaje się do pisania automatyczne testy nieprzejrzyste, w których kod nie opiera się na wewnętrznym kodzie szczegóły implementacji aplikacji docelowej.

Najważniejsze funkcje platformy testowej UI Automator to:

.

Uzyskiwanie dostępu do stanu urządzenia

Platforma testowa UI Automator zapewnia dostęp do klasy UiDevice i wykonywać operacje na urządzeniu, na którym działa aplikacja docelowa. Dostępne opcje wywołuje jego metody dostępu do właściwości urządzenia, takich jak bieżąca orientacja czy rozmiar interfejsu. Zajęcia UiDevice umożliwiają też wykonywanie tych czynności: czynności:

  1. Zmień obrót urządzenia.
  2. Naciśnij klawisze sprzętowe, na przykład „zwiększ głośność”.
  3. Naciśnij przycisk Wstecz, Ekran główny lub Menu.
  4. Otwórz obszar powiadomień.
  5. Zrób zrzut ekranu bieżącego okna.

Na przykład aby symulować naciśnięcie przycisku ekranu głównego, wywołaj UiDevice.pressHome() .

Interfejsy API Automator UI

Interfejsy UI Automator API umożliwiają pisanie zaawansowanych testów bez konieczności o szczegółach implementacji docelowej aplikacji. Za pomocą te interfejsy API do przechwytywania i manipulacji komponentami interfejsu w wielu aplikacjach:

  • UiObject2: reprezentuje element interfejsu widoczny na urządzeniu.
  • BySelector: określa kryteria pasujących elementów interfejsu.
  • By: tworzy BySelector w zwięzły sposób.
  • Configurator: umożliwia ustawianie kluczowych parametrów uruchamiania testów UI Automator.
.

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 UI Automator

Zanim utworzysz test UI za pomocą Automatora UI, skonfiguruj test lokalizacji kodu źródłowego i zależności projektu, zgodnie z opisem w sekcji Konfigurowanie projektu w przypadku AndroidaX Test.

W pliku build.gradle modułu aplikacji na Androida musisz ustawić zależność odwołanie do biblioteki UI Automator:

Kotlin

dependencies {
  ...
  androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}

Odlotowe

dependencies {
  ...
  androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}

Aby zoptymalizować testy UI Automator, sprawdź najpierw Dopilnuj, aby komponenty interfejsu były dostępne. Wskazówki dotyczące optymalizacji opisane w kolejnych dwóch sekcjach.

Sprawdzanie interfejsu użytkownika na urządzeniu

Zanim zaprojektujesz test, sprawdź komponenty interfejsu widoczne na urządzenia. Aby mieć pewność, że testy UI Automator mają dostęp do tych komponentów, sprawdź, czy te komponenty mają widoczne etykiety tekstowe, android:contentDescription lub obie te wartości.

Narzędzie uiautomatorviewer udostępnia wygodny interfejs wizualny do badania hierarchię układu i wyświetlać właściwości komponentów UI, które są widoczne na pierwszym planie urządzenia. Te informacje umożliwiają tworzenie do szczegółowych testów za pomocą Automatora UI. Możesz na przykład utworzyć selektor interfejsu pasujące do konkretnej widocznej właściwości.

Aby uruchomić narzędzie uiautomatorviewer:

  1. Uruchom aplikację docelową na urządzeniu fizycznym.
  2. Podłącz urządzenie do komputera, którego używasz do programowania.
  3. Otwórz okno terminala i przejdź do katalogu <android-sdk>/tools/.
  4. Uruchom narzędzie za pomocą tego polecenia:
 $ uiautomatorviewer

Aby wyświetlić właściwości interfejsu aplikacji:

  1. W interfejsie aplikacji uiautomatorviewer kliknij przycisk Zrzut ekranu urządzenia.
  2. Najedź na zrzut w panelu po lewej stronie, aby wyświetlić komponenty interfejsu jest wykrywane przez narzędzie uiautomatorviewer. Właściwości są wymienione w niższy a w prawym górnym rogu – hierarchię układu.
  3. Opcjonalnie kliknij przycisk Toggle NAF Nodes (Przełącz węzły NAF), aby wyświetlić komponenty interfejsu. niedostępne dla UI Automator. Mogą być dostępne tylko niektóre informacje dostępnych dla tych komponentów.

Informacje o typowych typach komponentów UI udostępnianych przez Androida znajdziesz w sekcji Użytkownik

Upewnij się, że informacje o Twojej aktywności są dostępne

Platforma testowa UI Automator działa lepiej w aplikacjach z zaimplementowanymi Ułatwienia dostępu na Androidzie. Gdy używasz elementów interfejsu typu View, podklasy klasy View z pakietu SDK, nie musisz implementować ułatwień dostępu możesz się z nami skontaktować.

Niektóre aplikacje korzystają jednak z niestandardowych elementów interfejsu, by zapewnić jeszcze lepsze wrażenia użytkownikom. Nie zapewniają one automatycznej obsługi ułatwień dostępu. Jeśli Twoja aplikacja zawiera wystąpienia podklasy klasy View, która nie pochodzi z pakietu SDK, utwórz pamiętaj o dodaniu do tych elementów ułatwień dostępu, wypełniając następujące kroki:

  1. Utwórz konkretną klasę, która rozszerza funkcję ExploreByTouchHelper.
  2. Powiąż instancję nowej klasy z określonym niestandardowym elementem interfejsu przez: przez wywołanie setAccessibilityDelegate().

Dodatkowe wskazówki dotyczące dodawania ułatwień dostępu do widoku niestandardowego elementów zawiera artykuł o tworzeniu widoków niestandardowych z ułatwieniami dostępu. Aby dowiedzieć się więcej o: ogólnych sprawdzonych metod związanych z ułatwieniami dostępu w Androidzie znajdziesz w artykule Udoskonalanie aplikacji. Ułatwienia dostępu.

Utwórz klasę testową Automator UI

Klasa testowa UI Automator powinna być napisana w taki sam sposób jak test JUnit 4 zajęcia. Aby dowiedzieć się więcej o tworzeniu klas testowych JUnit 4 i korzystaniu z JUnit 4 asercji i adnotacji znajdziesz w artykule Create an Instrumented Unit Test Class (Tworzenie instrumentowanej klasy testu jednostki).

Na początku testu dodaj adnotację @RunWith(AndroidJUnit4.class) definicji klasy. Musisz też podać klasę AndroidJUnitRunner, podane w narzędziu AndroidX Test jako domyślny program do uruchamiania testów. Ten krok został opisany . znajdziesz w artykule Przeprowadzanie testów UI Automator na urządzeniu lub emulatorze.

Zaimplementuj ten model programowania na zajęciach testowych UI Automator:

  1. Pobierz obiekt UiDevice, aby uzyskać dostęp do urządzenia, które chcesz przetestować, wywołując metody getInstance() i przekazanie jej obiektu Instrumentation jako argumentu.
  2. Pobierz obiekt UiObject2, aby uzyskać dostęp do komponentu interfejsu wyświetlanego w urządzenia (np. bieżący widok na pierwszym planie), przez wywołanie funkcji findObject().
  3. Symulowanie określonej interakcji użytkownika w danym komponencie interfejsu: wywołuje metodę UiObject2; Na przykład zadzwoń scrollUntil(), aby przewijać, i setText(), aby edytować pole tekstowe. Możesz wywołać interfejsy API w krokach 2 i 3 w razie potrzeby w celu przetestowania bardziej złożonych interakcji użytkowników, wiele komponentów UI lub sekwencji działań użytkownika.
  4. Sprawdź, czy interfejs odzwierciedla oczekiwany stan lub działanie po tym użytkowniku interakcji użytkowników.

Szczegółowo opisujemy te czynności w poniższych sekcjach.

Uzyskiwanie dostępu do komponentów interfejsu

Obiekt UiDevice to podstawowy sposób, w jaki uzyskujesz dostęp do stanu urządzenia. W testach możesz wywoływać UiDevice metod, 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, np. wymusić obrót urządzenia czy naciśnięcie pada kierunkowego. oraz naciskając przyciski Ekran główny i Menu.

Warto rozpoczynać test na ekranie głównym urządzenia. Od ekranu głównego (lub innej lokalizacji początkowej wybranej w urządzeniu), możesz wywoływać metody udostępnione przez interfejs UI Automator API, aby wybierać i wykonywać działania z określonymi elementami interfejsu.

Ten fragment kodu pokazuje, jak test może uzyskać wystąpienie UiDevice i symulują 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 tym przykładzie instrukcja @SdkSuppress(minSdkVersion = 18) pomaga upewnić się, ż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.

Użyj metody findObject(), aby pobrać UiObject2, który reprezentuje widok zgodny z podanymi kryteriami selektora. UiObject2 – możesz użyć ponownie i instancji utworzonych w innych częściach testowania aplikacji, zależnie od potrzeb. Pamiętaj, że platforma testowa UI Automator wyszukuje na bieżącym ekranie dopasowanie za każdym razem, gdy test używa instancji UiObject2 do kliknięcia interfejsu użytkownika lub wysłać zapytanie dotyczące właściwości.

Ten fragment kodu pokazuje, jak test może utworzyć obiekt UiObject2 reprezentujących przyciski Anuluj i 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 aplikacji, użyj By, aby utworzyć instancję BySelector. BySelector reprezentuje zapytanie o konkretne elementy wyświetlanego interfejsu użytkownika.

Jeśli zostanie znalezione więcej niż jeden pasujący element, pierwszy z nich hierarchia układu jest zwracana jako docelowy UiObject2. Podczas tworzenia BySelector, możesz połączyć kilka usług, aby ulepszyć . Jeśli nie zostanie znaleziony pasujący element interfejsu, zwracany jest element null.

Do zagnieżdżania możesz użyć metody hasChild() lub hasDescendant() wiele instancji BySelector. Na przykład ten przykładowy kod pokazuje jak test może określić wyszukiwanie w celu znalezienia pierwszego elementu ListView, który zawiera podrzędny element interfejsu z właściwością text.

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")
        )
);

Określenie stanu obiektu w kryteriach selektora może być przydatne. Dla: Jeśli na przykład chcesz wybrać listę wszystkich zaznaczonych elementów, tak aby można było odznacz je, wywołaj metodę checked() z argumentem ustawionym na „true”.

Wykonywanie działań

Gdy test uzyska obiekt UiObject2, możesz wywołać metody w klasę UiObject2 do wykonywania interakcji z użytkownikiem w komponencie interfejsu użytkownika reprezentowanych 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() : po wyczyszczeniu pola edytowalnego umieszcza tekst w polu zawartość pola. I na odwrót: metoda clear() usuwa istniejący tekst. w polu do edycji.
  • swipe() : wykonuje działanie przesuwania w określonym kierunku.
  • scrollUntil(): wykonuje działanie przewijania w określonym kierunku. do czasu spełnienia wymagań Condition lub EventCondition.

Platforma testowa UI Automator umożliwia wysłanie intencji lub uruchomienia działanie bez użycia poleceń powłoki, dzięki któremu można uzyskać kontekst. przez getContext().

Ten fragment kodu pokazuje, jak test może użyć intencji do uruchamiania tagu w trakcie testowania. Ta metoda jest przydatna, gdy chcesz tylko przetestować aplikacji kalkulatora i 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);
}

Zweryfikuj wyniki

Parametr InstrumentationTestCase rozszerza typ TestCase, dzięki czemu możesz używać: standardowych metod JUnit Assert, które pozwalają sprawdzić, czy komponenty UI w aplikacji są zwracane oczekiwanych wyników.

Poniższy fragment kodu pokazuje, jak za pomocą testu znaleźć kilka przycisków w aplikacji Kalkulator, klikaj po kolei, a następnie sprawdź, czy 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());
}

Przeprowadzaj testy UI Automator na urządzeniu lub emulatorze

Testy UI Automator możesz uruchamiać w Android Studio lub w wiersza poleceń. Pamiętaj, aby określić AndroidJUnitRunner jako domyślną narzędzia uruchamiającego w projekcie.

Więcej przykładów

Interakcje z interfejsem systemu

Automator UI może wchodzić w interakcje ze wszystkimi elementami na ekranie, w tym z systemem poza aplikacją, jak widać 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 przeniesienia

Wyłącz przeszkadzać
Rysunek 1. Automator UI wyłącza tryb Nie przeszkadzać na urządzeniu urządzenia testowego.

Przejścia ekranu mogą być czasochłonne, a ich czas trwania może być zawodny. po wykonaniu operacji narzędzie UI Automator powinien poczekać. Automator UI umożliwia to na różne sposoby:

Ten fragment kodu pokazuje, jak za pomocą Automatora UI wyłączyć opcję Nie trybu zakłócania w ustawieniach systemu przy użyciu metody performActionAndWait(), która oczekuje 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 Androida znajdziesz w poniższe zasoby.

Dokumentacja źródłowa:

Próbki