UI Automator Legacy API verwenden

UI Automator ist ein UI-Testframework, das für funktionsbezogene UI-Tests über verschiedene Apps hinweg geeignet ist, sowohl für System- als auch für installierte Apps. Mit den UI Automator APIs können Sie mit sichtbaren Elementen auf einem Gerät interagieren, unabhängig davon, welche Activity gerade im Fokus steht. So können Sie beispielsweise das Menü „Einstellungen“ oder den App-Launcher auf einem Testgerät öffnen. Ihr Test kann eine UI-Komponente mithilfe praktischer Deskriptoren wie dem in dieser Komponente angezeigten Text oder der Inhaltsbeschreibung suchen.

Das UI Automator-Testframework ist eine instrumentierungsbasierte API und funktioniert mit dem AndroidJUnitRunner Test-Runner. Es eignet sich gut zum Schreiben von automatisierten Tests im Stil einer Blackbox, bei denen der Testcode nicht auf internen Implementierungsdetails der Ziel-App basiert.

Die wichtigsten Funktionen des UI Automator-Testframeworks sind:

  • Eine API zum Abrufen von Statusinformationen und Ausführen von Vorgängen auf dem Zielgerät. Weitere Informationen finden Sie unter Auf Gerätestatus zugreifen.
  • APIs, die UI-Tests über verschiedene Apps hinweg unterstützen. Weitere Informationen finden Sie unter UI Automator APIs.

Auf Gerätestatus zugreifen

Das UI Automator-Testframework bietet die Klasse UiDevice, mit der Sie auf das Gerät zugreifen und Vorgänge darauf ausführen können, auf dem die Ziel-App ausgeführt wird. Sie können die Methoden aufrufen, um auf Geräteeigenschaften wie die aktuelle Ausrichtung oder die Anzeigegröße zuzugreifen. Mit der Klasse UiDevice können Sie auch die folgenden Aktionen ausführen:

  1. Die Geräteausrichtung ändern.
  2. Hardwaretasten wie „Lauter“ drücken.
  3. Die Tasten „Zurück“, „Startbildschirm“ oder „Menü“ drücken.
  4. Die Benachrichtigungsleiste öffnen.
  5. Einen Screenshot des aktuellen Fensters erstellen.

Wenn Sie beispielsweise einen Druck auf die Startbildschirmtaste simulieren möchten, rufen Sie die Methode UiDevice.pressHome() auf.

UI Automator APIs

Mit den UI Automator APIs können Sie robuste Tests schreiben, ohne die Implementierungsdetails der Ziel-App zu kennen. Mit diesen APIs können Sie UI-Komponenten in mehreren Apps erfassen und bearbeiten:

  • UiObject2: Stellt ein UI-Element dar, das auf dem Gerät sichtbar ist.
  • BySelector: Gibt Kriterien für den Abgleich von UI-Elementen an.
  • By: Erstellt BySelector auf prägnante Weise.
  • Configurator: Ermöglicht das Festlegen wichtiger Parameter für die Ausführung von UI Automator-Tests.

Der folgende Code zeigt beispielsweise, wie Sie ein Testskript schreiben können, das eine Gmail-App auf dem Gerät öffnet:

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

UI Automator einrichten

Bevor Sie Ihren UI-Test mit UI Automator erstellen, müssen Sie den Speicherort des Test quellcodes und die Projektabhängigkeiten konfigurieren, wie unter Projekt für AndroidX Test einrichten beschrieben.

In der Datei build.gradle Ihres Android-App-Moduls müssen Sie einen Abhängigkeitsverweis auf die UI Automator-Bibliothek festlegen:

Kotlin

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

Groovy

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

Um Ihre UI Automator-Tests zu optimieren, sollten Sie zuerst die UI-Komponenten der Ziel-App prüfen und sicherstellen, dass sie barrierefrei sind. Diese Optimierungstipps werden in den nächsten beiden Abschnitten beschrieben.

UI auf einem Gerät prüfen

Bevor Sie Ihren Test entwerfen, prüfen Sie die UI-Komponenten, die auf dem Gerät sichtbar sind. Damit Ihre UI Automator-Tests auf diese Komponenten zugreifen können, müssen sie sichtbare Textlabels, android:contentDescription Werte oder beides haben.

Das Tool uiautomatorviewer bietet eine praktische visuelle Benutzeroberfläche, mit der Sie die Layout-Hierarchie prüfen und die Eigenschaften von UI-Komponenten ansehen können, die im Vordergrund des Geräts sichtbar sind. Mit diesen Informationen können Sie detailliertere Tests mit UI Automator erstellen. Sie können beispielsweise einen UI-Selektor erstellen, der mit einer bestimmten sichtbaren Eigenschaft übereinstimmt.

So starten Sie das Tool uiautomatorviewer:

  1. Starten Sie die Ziel-App auf einem physischen Gerät.
  2. Verbinden Sie das Gerät mit Ihrer Entwicklungsmaschine.
  3. Öffnen Sie ein Terminalfenster und wechseln Sie zum Verzeichnis <android-sdk>/tools/.
  4. Führen Sie das Tool mit diesem Befehl aus:
 $ uiautomatorviewer

So rufen Sie die UI-Eigenschaften Ihrer Anwendung auf:

  1. Klicken Sie in der Benutzeroberfläche von uiautomatorviewer auf die Schaltfläche Device Screenshot (Geräte-Screenshot).
  2. Bewegen Sie den Mauszeiger im linken Bereich über den Snapshot, um die UI-Komponenten zu sehen, die vom Tool uiautomatorviewer erkannt wurden. Die Eigenschaften werden im unteren rechten Bereich und die Layout-Hierarchie im oberen rechten Bereich aufgeführt.
  3. Optional können Sie auf die Schaltfläche Toggle NAF Nodes (NAF-Knoten umschalten) klicken, um UI-Komponenten zu sehen, auf die UI Automator nicht zugreifen kann. Für diese Komponenten sind möglicherweise nur begrenzte Informationen verfügbar.

Informationen zu den gängigen Arten von UI-Komponenten, die von Android bereitgestellt werden, finden Sie unter Benutzeroberfläche.

Sicherstellen, dass Ihre Aktivität barrierefrei ist

Das UI Automator-Testframework funktioniert besser bei Apps, in denen Android-Bedienungshilfen implementiert sind. Wenn Sie UI-Elemente vom Typ View oder eine Unterklasse von View aus dem SDK verwenden, müssen Sie keine Bedienungshilfen implementieren, da dies bereits in diesen Klassen erfolgt ist.

Einige Apps verwenden jedoch benutzerdefinierte UI-Elemente, um eine bessere Nutzererfahrung zu bieten. Solche Elemente bieten keine automatische Unterstützung für Bedienungshilfen. Wenn Ihre App Instanzen einer Unterklasse von View enthält, die nicht aus dem SDK stammt, müssen Sie diesen Elementen Bedienungshilfen hinzufügen. Führen Sie dazu die folgenden Schritte aus:

  1. Erstellen Sie eine konkrete Klasse, die von ExploreByTouchHelper abgeleitet wird.
  2. Verknüpfen Sie eine Instanz Ihrer neuen Klasse mit einem bestimmten benutzerdefinierten UI-Element, indem Sie setAccessibilityDelegate()aufrufen.

Weitere Informationen zum Hinzufügen von Bedienungshilfen zu benutzerdefinierten Ansicht elementen finden Sie unter Barrierefreie benutzerdefinierte Ansichten erstellen. Weitere Informationen zu allgemeinen Best Practices für Bedienungshilfen unter Android finden Sie unter Apps barrierefreier machen.

UI Automator-Testklasse erstellen

Ihre UI Automator-Testklasse sollte genauso geschrieben werden wie eine JUnit 4-Testklasse. Weitere Informationen zum Erstellen von JUnit 4-Testklassen und zur Verwendung von JUnit 4 Assertions und -Annotationen finden Sie unter Instrumentierte Einheitentestklasse erstellen.

Fügen Sie die Annotation @RunWith(AndroidJUnit4.class) am Anfang der Definition Ihrer Testklasse hinzu. Sie müssen auch die Klasse AndroidJUnitRunner, die in AndroidX Test bereitgestellt wird, als Standard-Test-Runner angeben. Dieser Schritt wird unter UI Automator-Tests auf einem Gerät oder Emulator ausführen ausführlicher beschrieben.

Implementieren Sie das folgende Programmiermodell in Ihrer UI Automator-Testklasse:

  1. Rufen Sie ein UiDevice Objekt auf, um auf das Gerät zuzugreifen, das Sie testen möchten. Rufen Sie dazu die getInstance() Methode auf und übergeben Sie ihr ein Instrumentation Objekt als Argument.
  2. Rufen Sie ein UiObject2-Objekt auf, um auf eine UI-Komponente zuzugreifen, die auf dem Gerät angezeigt wird (z. B. die aktuelle Ansicht im Vordergrund). Rufen Sie dazu die findObject()-Methode auf.
  3. Simulieren Sie eine bestimmte Nutzerinteraktion, die für diese UI-Komponente ausgeführt werden soll, indem Sie eine UiObject2 Methode aufrufen. Rufen Sie beispielsweise scrollUntil() auf, um zu scrollen, und setText(), um ein Textfeld zu bearbeiten. Sie können die APIs in Schritt 2 und 3 nach Bedarf wiederholt aufrufen, um komplexere Nutzerinteraktionen zu testen, die mehrere UI-Komponenten oder Sequenzen von Nutzeraktionen umfassen.
  4. Prüfen Sie, ob die UI nach diesen Nutzerinteraktionen den erwarteten Status oder das erwartete Verhalten zeigt.

Diese Schritte werden in den folgenden Abschnitten ausführlicher beschrieben.

Auf UI-Komponenten zugreifen

Das UiDevice-Objekt ist die primäre Möglichkeit, auf den Status des Geräts zuzugreifen und ihn zu bearbeiten. In Ihren Tests können Sie UiDevice-Methoden aufrufen, um den Zustand verschiedener Eigenschaften wie die aktuelle Ausrichtung oder die Anzeigegröße zu prüfen. Ihr Test kann das UiDevice-Objekt verwenden, um Aktionen auf Geräteebene auszuführen, z. B. das Gerät in eine bestimmte Ausrichtung zu zwingen, Hardwaretasten des Steuerkreuzes zu drücken und die Tasten „Startbildschirm“ und „Menü“ zu drücken.

Es empfiehlt sich, den Test auf dem Startbildschirm des Geräts zu beginnen. Auf dem Startbildschirm (oder an einem anderen Startort, den Sie auf dem Gerät ausgewählt haben) können Sie die von der UI Automator API bereitgestellten Methoden aufrufen, um bestimmte UI-Elemente auszuwählen und mit ihnen zu interagieren.

Das folgende Code-Snippet zeigt, wie Ihr Test eine Instanz von UiDevice abrufen und einen Druck auf die Startbildschirmtaste simulieren kann:

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

Im Beispiel sorgt die Anweisung @SdkSuppress(minSdkVersion = 18) dafür, dass Tests nur auf Geräten mit Android 4.3 (API-Level 18) oder höher ausgeführt werden, wie vom UI Automator-Framework gefordert.

Verwenden Sie die Methode findObject(), um ein UiObject2 abzurufen, das eine Ansicht darstellt, die den angegebenen Selektorkriterien entspricht. Sie können die erstellten UiObject2-Instanzen nach Bedarf in anderen Teilen Ihrer App-Tests wiederverwenden. Das UI Automator-Testframework sucht jedes Mal auf dem aktuellen Display nach einer Übereinstimmung, wenn Ihr Test eine UiObject2-Instanz verwendet, um auf ein UI-Element zu klicken oder eine Eigenschaft abzufragen.

Das folgende Snippet zeigt, wie Ihr Test UiObject2-Instanzen erstellen kann, die eine Schaltfläche „Abbrechen“ und eine Schaltfläche „OK“ in einer App darstellen.

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();
}

Selektor angeben

Wenn Sie auf eine bestimmte UI-Komponente in einer App zugreifen möchten, verwenden Sie die By Klasse, um eine BySelector Instanz zu erstellen. BySelector stellt eine Abfrage für bestimmte Elemente in der angezeigten UI dar.

Wenn mehr als ein übereinstimmendes Element gefunden wird, wird das erste übereinstimmende Element in der Layout-Hierarchie als Ziel-UiObject2 zurückgegeben. Beim Erstellen eines BySelector können Sie mehrere Eigenschaften verketten, um die Suche zu verfeinern. Wenn kein übereinstimmendes UI-Element gefunden wird, wird null zurückgegeben.

Sie können die hasChild() oder hasDescendant() Methode verwenden, um mehrere BySelector Instanzen zu verschachteln. Das folgende Codebeispiel zeigt wie Ihr Test eine Suche angeben kann, um die erste ListView zu finden, die ein untergeordnetes UI-Element mit der Texteigenschaft enthält.

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

Es kann hilfreich sein, den Objektstatus in Ihren Selektorkriterien anzugeben. Wenn Sie beispielsweise eine Liste aller ausgewählten Elemente auswählen möchten, damit Sie sie deaktivieren können, rufen Sie die checked() Methode auf und setzen Sie das Argument auf „true“.

Aktionen durchführen

Sobald Ihr Test ein UiObject2-Objekt abgerufen hat, können Sie die Methoden in der Klasse UiObject2 aufrufen, um Nutzerinteraktionen für die UI-Komponente auszuführen, die durch dieses Objekt dargestellt wird. Sie können beispielsweise folgende Aktionen angeben:

  • click() : Klickt auf die Mitte der sichtbaren Begrenzungen des UI-Elements.
  • drag() : Zieht dieses Objekt an beliebige Koordinaten.
  • setText() : Legt den Text in einem bearbeitbaren Feld fest, nachdem der Inhalt des Felds gelöscht wurde. Umgekehrt löscht die clear() Methode den vorhandenen Text in einem bearbeitbaren Feld.
  • swipe() : Führt die Wischaktion in der angegebenen Richtung aus.
  • scrollUntil(): Führt die Scrollaktion in der angegebenen Richtung aus bis Condition oder EventCondition erfüllt ist.

Mit dem UI Automator-Testframework können Sie eine Intent senden oder eine Activity starten, ohne Shell-Befehle zu verwenden. Rufen Sie dazu ein Context Objekt über getContext() ab.

Das folgende Snippet zeigt, wie Ihr Test eine Intent verwenden kann, um die zu testende App zu starten. Dieser Ansatz ist nützlich, wenn Sie nur die Taschenrechner-App testen möchten und sich nicht für den Launcher interessieren.

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

Ergebnisse bestätigen

Die InstrumentationTestCase wird von TestCase abgeleitet. Daher können Sie Standard-JUnit-Assert-Methoden verwenden, um zu testen, ob UI-Komponenten in der App die erwarteten Ergebnisse zurückgeben.

Das folgende Snippet zeigt, wie Ihr Test mehrere Schaltflächen in einer Taschenrechner-App finden, sie der Reihe nach anklicken und dann prüfen kann, ob das richtige Ergebnis angezeigt wird.

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());
}

UI Automator-Tests auf einem Gerät oder Emulator ausführen

Sie können UI Automator-Tests in Android Studio oder über die Befehlszeile ausführen. Geben Sie AndroidJUnitRunner als Standard-Instrumentierungs-Runner in Ihrem Projekt an.

Weitere Beispiele

Mit der System-UI interagieren

UI Automator kann mit allen Elementen auf dem Bildschirm interagieren, einschließlich Systemelementen außerhalb Ihrer App, wie in den folgenden Code-Snippets gezeigt:

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

Auf Übergänge warten

„Bitte nicht stören“ deaktivieren
Abbildung 1. UI Automator deaktiviert den Modus „Nicht stören“ auf einem Testgerät.

Bildschirmübergänge können Zeit in Anspruch nehmen und ihre Dauer lässt sich nicht zuverlässig vorhersagen. Daher sollten Sie UI Automator nach der Ausführung von Vorgängen warten lassen. UI Automator bietet dafür mehrere Methoden:

Das folgende Code-Snippet zeigt, wie Sie UI Automator verwenden können, um den Modus „Nicht stören“ in den Systemeinstellungen zu deaktivieren. Dazu wird die Methode performActionAndWait() verwendet, die auf Übergänge wartet:

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

Zusätzliche Ressourcen

Weitere Informationen zur Verwendung von UI Automator in Android-Tests finden Sie in den folgenden Ressourcen.

Referenzdokumentation:

Beispiele