Korzystanie z interfejsu UI Automator Legacy API

UI Automator to platforma do testowania interfejsu, która nadaje się do testowania funkcjonalnego interfejsu w różnych aplikacjach systemowych i zainstalowanych. Interfejsy UI Automator API umożliwiają interakcję z widocznymi elementami na urządzeniu niezależnie od tego, która Activity jest aktywna. Dzięki temu możesz wykonywać operacje takie jak otwieranie menu Ustawienia lub programu uruchamiającego aplikacje na urządzeniu testowym. Test może wyszukiwać komponent interfejsu za pomocą wygodnych deskryptorów, takich jak tekst wyświetlany w tym komponencie lub jego opis.

Platforma testowa UI Automator to interfejs API oparty na instrumentacji, który współpracuje z programem do uruchamiania testów AndroidJUnitRunner. Nadaje się do pisania automatycznych testów typu „czarna skrzynka”, w których kod testu nie zależy od wewnętrznych szczegółów implementacji testowanej aplikacji.

Główne funkcje platformy testowej UI Automator to:

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ć jego metody, aby uzyskać dostęp do właściwości urządzenia, takich jak bieżąca orientacja czy rozmiar wyświetlacza. W przypadku zajęć UiDevice możesz też wykonywać te czynności:

  1. Zmień orientację urządzenia.
  2. Naciśnij przyciski sprzętowe, np. „zwiększ głośność”.
  3. Naciśnij przycisk Wstecz, ekranu głównego lub Menu.
  4. Otwórz obszar powiadomień.
  5. Zrób zrzut ekranu bieżącego okna.

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

Interfejsy UI Automator API

Interfejsy API UI Automator umożliwiają pisanie niezawodnych testów bez konieczności poznawania szczegółów implementacji testowanej aplikacji. Za pomocą tych interfejsów API możesz przechwytywać komponenty interfejsu w różnych aplikacjach i nimi manipulować:

  • UiObject2: oznacza element interfejsu widoczny na urządzeniu.
  • BySelector: określa kryteria dopasowywania elementów interfejsu.
  • By: zwięźle tworzy BySelector.
  • Configurator: umożliwia ustawienie kluczowych parametrów przeprowadzania testów UI Automator.

Na przykład poniższy kod pokazuje, jak 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);

Konfigurowanie UI Automatora

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

Groovy

dependencies { ... androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0" }

Aby zoptymalizować testowanie za pomocą UI Automatora, najpierw sprawdź komponenty interfejsu aplikacji docelowej i upewnij się, że są dostępne. Wskazówki dotyczące optymalizacji opisujemy w 2 następnych sekcjach.

Sprawdzanie interfejsu na urządzeniu

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

Narzędzie uiautomatorviewer zapewnia 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 Automatora. Możesz na przykład utworzyć selektor interfejsu, który pasuje do określonej widocznej właściwości.

Aby uruchomić narzędzie uiautomatorviewer:

  1. Uruchom docelową aplikację na urządzeniu fizycznym.
  2. Podłącz urządzenie do komputera deweloperskiego.
  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 uiautomatorviewer kliknij przycisk Zrzut ekranu urządzenia.
  2. Najedź kursorem na zrzut ekranu w panelu po lewej stronie, aby zobaczyć komponenty interfejsu zidentyfikowane przez narzędzie uiautomatorviewer. Właściwości są wymienione w panelu w prawym dolnym rogu, a hierarchia układu – w panelu w prawym górnym rogu.
  3. Opcjonalnie kliknij przycisk Toggle NAF Nodes, aby wyświetlić komponenty interfejsu, które są niedostępne dla UI Automatora. W przypadku tych komponentów może być dostępnych tylko ograniczona liczba informacji.

Więcej informacji o najpopularniejszych typach komponentów interfejsu udostępnianych przez Androida znajdziesz w artykule Interfejs użytkownika.

Sprawdź, czy aktywność jest dostępna

Platforma testowa UI Automator lepiej sprawdza się w przypadku aplikacji, w których zaimplementowano 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 ułatwień dostępu, ponieważ te klasy już to robią.

Niektóre aplikacje używają jednak niestandardowych elementów interfejsu, aby zapewnić użytkownikom większą wygodę. Takie elementy nie będą automatycznie obsługiwać funkcji 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:

  1. Utwórz klasę konkretną, która rozszerza klasę ExploreByTouchHelper.
  2. Powiąż instancję nowej klasy z określonym niestandardowym elementem interfejsu, wywołując metodę 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 Ułatwianie dostępu do 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ą.

Dodaj adnotację @RunWith(AndroidJUnit4.class) na początku definicji klasy testowej. Musisz też określić klasę AndroidJUnitRunner, która jest dostępna w AndroidX Test, jako domyślny mechanizm uruchamiania testów. Ten krok został szczegółowo opisany w artykule Uruchamianie testów UI Automator na urządzeniu lub emulatorze.

W klasie testu UI Automator zaimplementuj ten model programowania:

  1. Aby uzyskać dostęp do urządzenia, które chcesz przetestować, wywołaj metodę getInstance() i przekaż jej obiekt Instrumentation jako argument.UiDevice
  2. Aby uzyskać dostęp do komponentu interfejsu wyświetlanego na urządzeniu (np. bieżącego widoku na pierwszym planie), wywołaj metodę findObject(). Zwróci ona obiekt UiObject2.
  3. Symuluj konkretną interakcję użytkownika z tym komponentem interfejsu, wywołując metodę UiObject2, np. 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 przetestować bardziej złożone interakcje użytkownika, które obejmują wiele komponentów interfejsu lub sekwencji działań użytkownika.
  4. Sprawdź, czy interfejs odzwierciedla oczekiwany stan lub zachowanie po wykonaniu tych interakcji użytkownika.

Szczegółowe informacje o tych krokach znajdziesz w sekcjach poniżej.

Komponenty interfejsu dostępu

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 wyświetlacza. 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 kierunkowych i przycisków Home oraz Menu.

Warto rozpocząć test od ekranu głównego urządzenia. Na ekranie głównym (lub w innym miejscu początkowym wybranym na urządzeniu) możesz wywoływać metody udostępniane przez interfejs UI Automator API, aby wybierać określone elementy interfejsu i wchodzić z nimi w interakcję.

Poniższy fragment kodu pokazuje, jak test może uzyskać instancję UiDevice i zasymulować naciśnięcie przycisku Home:

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 API 18) lub nowszym, zgodnie z wymaganiami platformy UI Automator.

Użyj metody findObject(), aby pobrać obiekt UiObject2, który reprezentuje widok pasujący do podanych kryteriów selektora. W razie potrzeby możesz ponownie użyć UiObject2instancji utworzonych w innych częściach testowania aplikacji. Pamiętaj, że platforma testowa UI Automator za każdym razem, gdy test używa instancji UiObject2 do kliknięcia elementu interfejsu lub wysłania zapytania o właściwość, przeszukuje bieżący wyświetlacz w poszukiwaniu dopasowania.

Poniższy fragment kodu pokazuje, jak test może tworzyć instancje UiObject2 reprezentujące przycisk 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ś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 dotyczące konkretnych elementów wyświetlanego interfejsu.

Jeśli zostanie znalezionych więcej niż 1 pasujący element, jako element 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, zwracana jest wartość null.

Możesz użyć metody hasChild() lub hasDescendant(), aby zagnieździć wiele instancji BySelector. Na przykład poniższy przykładowy kod pokazuje, jak test może określić wyszukiwanie pierwszego elementu 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 wartość „true”.

Wykonywanie działań

Gdy test uzyska obiekt UiObject2, możesz wywołać metody w klasie UiObject2, aby przeprowadzić interakcje użytkownika z komponentem 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 polu z możliwością edytowania po wyczyszczeniu zawartości pola. Z kolei metoda clear() usuwa istniejący tekst z pola edytowalnego.
  • swipe() : wykonuje przesuwanie w określonym kierunku.
  • scrollUntil(): wykonuje przewijanie w określonym kierunku, dopóki nie zostanie spełniony warunek Condition lub EventCondition.

Platforma testowa UI Automator umożliwia wysyłanie intencji lub uruchamianie aktywności bez używania poleceń powłoki. Wystarczy uzyskać obiekt Context za pomocą getContext().

Poniższy fragment kodu pokazuje, jak test może używać Intent do uruchamiania testowanej aplikacji. Jest to przydatne, gdy chcesz tylko przetestować aplikację Kalkulator 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

Klasa InstrumentationTestCase rozszerza klasę TestCase, więc możesz używać standardowych metod Assert JUnit do testowania, czy komponenty interfejsu w aplikacji zwracają oczekiwane wyniki.

Poniższy fragment pokazuje, jak test może zlokalizować 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 z wiersza poleceń. Upewnij się, że w projekcie jako domyślny program uruchamiający testy integracyjne podano AndroidJUnitRunner.

Więcej przykładów

Korzystanie z interfejsu systemu

UI Automator może wchodzić w interakcje ze wszystkimi elementami na ekranie, w tym z elementami systemu poza aplikacją, jak pokazują poniższe 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());

Czekaj na przejścia

Wyłącz zakłócanie
Rysunek 1. UI Automator wyłącza tryb Nie przeszkadzać na urządzeniu testowym.

Przejścia między ekranami mogą trwać długo, a przewidywanie ich czasu trwania jest zawodne, dlatego po wykonaniu operacji UI Automator powinien poczekać. UI Automator udostępnia kilka metod:

Poniższy fragment kodu pokazuje, jak za pomocą UI Automatora 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 Automatora w testach na Androida znajdziesz w tych materiałach.

Dokumentacja:

Próbki