Tests mit von Gradle verwalteten Geräten skalieren

Von Gradle verwaltete Geräte verbessern Konsistenz, Leistung und Zuverlässigkeit für Ihre automatisierten instrumentierten Tests. Mit dieser Funktion, die ab API-Level 27 verfügbar ist, können Sie virtuelle oder Remote-physische Testgeräte in den Gradle-Dateien Ihres Projekts konfigurieren. Das Build-System verwendet die Konfigurationen, um diese Geräte beim Ausführen Ihrer automatisierten Tests vollständig zu verwalten, d. h. zu erstellen, bereitzustellen und zu entfernen.

Durch diese Funktion erhält Gradle nicht nur Einblick in die von Ihnen ausgeführten Tests, sondern auch über den Lebenszyklus der Geräte. Dadurch wird die Qualität Ihrer Tests auf folgende Weise verbessert:

  • Behandelt gerätebezogene Probleme, um sicherzustellen, dass Ihre Tests ausgeführt werden
  • Bei virtuellen Geräten werden Emulator-Snapshots verwendet, um die Gerätestartzeit und die Arbeitsspeichernutzung zu verbessern und die Geräte zwischen den Tests in einem bereinigten Zustand wiederherzustellen.
  • Speichert Testergebnisse im Cache und führt nur Tests noch einmal aus, die wahrscheinlich unterschiedliche Ergebnisse liefern
  • Bietet eine einheitliche Umgebung zum Ausführen von Tests zwischen lokalen und Remote-Testläufen

Virtuelles Gradle-verwaltetes Gerät erstellen

Sie können in Ihrer Build-Datei auf Modulebene ein virtuelles Gerät angeben, das Gradle zum Testen Ihrer App verwenden soll. Mit dem folgenden Codebeispiel wird ein Pixel 2 mit API-Level 30 als von Gradle verwaltetes Gerät erstellt.

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

Groovig

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

Gerätegruppen definieren

Damit Sie Ihre Tests für mehrere Gerätekonfigurationen (z. B. verschiedene API-Level und Formfaktoren) skalieren können, können Sie mehrere von Gradle verwaltete Geräte definieren und einer benannten Gruppe hinzufügen. Gradle kann dann Ihre Tests auf allen Geräten in der Gruppe parallel ausführen.

Das folgende Beispiel zeigt zwei Geräte, die einer Gerätegruppe namens phoneAndTablet hinzugefügt wurden.

Kotlin

testOptions {
  managedDevices {
    localDevices {
      create("pixel2api29") { ... }
      create("nexus9api30") { ... }
    }
    groups {
      create("phoneAndTablet") {
        targetDevices.add(devices["pixel2api29"])
        targetDevices.add(devices["nexus9api30"])
      }
    }
  }
}

Groovig

testOptions {
  managedDevices {
    localDevices {
      pixel2api29 { ... }
      nexus9api30 { ... }
    }
    groups {
      phoneAndTablet {
        targetDevices.add(devices.pixel2api29)
        targetDevices.add(devices.nexus9api30)
      }
    }
  }
}

Tests ausführen

Verwenden Sie den folgenden Befehl, um Ihre Tests mit den von Ihnen konfigurierten Gradle-verwalteten Geräten auszuführen. device-name ist der Name des Geräts, das Sie in Ihrem Gradle-Build-Skript konfiguriert haben (z. B. pixel2api30) und BuildVariant ist die Build-Variante Ihrer App, die Sie testen möchten.

Unter Windows:

gradlew device-nameBuildVariantAndroidTest

Unter Linux oder macOS:

./gradlew device-nameBuildVariantAndroidTest

Verwenden Sie die folgenden Befehle, um Ihre Tests für eine Gruppe von Gradle-verwalteten Geräten auszuführen.

Unter Windows:

gradlew group-nameGroupBuildVariantAndroidTest

Unter Linux oder macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

Die Testausgabe enthält einen Pfad zu einer HTML-Datei, die den Testbericht enthält. Sie können die Testergebnisse auch zur weiteren Analyse in Android Studio importieren. Klicken Sie dazu in der IDE auf Ausführen > Testverlauf.

Test-Sharding aktivieren

Von Gradle verwaltete Geräte unterstützen Test-Fragmentierung, mit der Sie Ihre Testsuite auf mehrere identische virtuelle Geräteinstanzen, sogenannte Shards, aufteilen können, die parallel ausgeführt werden. Die Verwendung von Test-Sharding kann dazu beitragen, die Testausführungszeit auf Kosten zusätzlicher Rechenressourcen zu reduzieren.

Um die Anzahl der Shards festzulegen, die Sie in einem bestimmten Testlauf verwenden möchten, legen Sie in der Datei gradle.properties Folgendes fest:

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

Wenn Sie Ihre Tests mit dieser Option ausführen, stellen Gradle-verwaltete Geräte die Anzahl der Shards bereit, die Sie für jedes Geräteprofil im Testlauf angeben. Wenn Sie Ihre Tests also beispielsweise auf einer Gerätegruppe mit drei Geräten bereitgestellt und numManagedDeviceShards auf zwei festgelegt haben, stellen Gradle-verwaltete Geräte insgesamt sechs virtuelle Geräte für den Testlauf bereit.

Wenn die Tests abgeschlossen sind, gibt Gradle für jeden im Testlauf verwendeten Shard die Testergebnisse in einer .proto-Datei aus.

Automatisierte Testgeräte verwenden

Gradle-verwaltete Geräte unterstützen ein Emulatorgerät namens „Automated Test Device“ (ATD), das für die Reduzierung von CPU- und Arbeitsspeicherressourcen beim Ausführen Ihrer instrumentierten Tests optimiert ist. ATDs verbessern die Laufzeitleistung auf verschiedene Arten:

  • Vorinstallierte Apps entfernen, die sich normalerweise nicht zum Testen der App eignen
  • Hintergrunddienste deaktivieren, die normalerweise nicht zum Testen Ihrer App nützlich sind
  • Hardware-Rendering deaktivieren

Bevor Sie beginnen, sollten Sie Android-Emulator auf die neueste verfügbare Version aktualisieren. Geben Sie dann ein „-atd“-Image an, wenn Sie ein von Gradle verwaltetes Gerät in Ihrer Build-Datei auf Modulebene definieren:

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

Groovig

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

Bei anderen Gradle-verwalteten Geräten ist es auch möglich, Gerätegruppen zu erstellen. Zur weiteren Nutzung der Leistungsverbesserungen können Sie auch ATDs mit Testfragmentierung verwenden, um die Gesamtausführungszeit für Tests Ihrer Testsuite zu reduzieren.

Was wird aus ATD-Images entfernt?

ATDs arbeiten nicht nur im monitorlosen Modus, sondern optimieren auch die Leistung, indem sie Anwendungen und Dienste entfernen oder deaktivieren, die normalerweise nicht zum Testen des Anwendungscodes erforderlich sind. Die folgende Tabelle bietet einen Überblick über die Komponenten, die wir in ATD-Bildern entfernt oder deaktiviert haben, und Beschreibungen, warum sie möglicherweise nicht nützlich sind.

Was wird in ATD-Images entfernt? Warum Sie diese Informationen bei der Ausführung automatisierter Tests möglicherweise nicht benötigen
Google-Produkt-Apps:
  • E‑Mails
  • Maps
  • Chrome
  • Messages
  • Play Store und andere
Ihre automatisierten Tests sollten sich auf die Logik Ihrer eigenen App konzentrieren und gleichzeitig davon ausgehen, dass andere Apps oder die Plattform ordnungsgemäß funktionieren.

Mit Espresso-Intents können Sie Ihre ausgehenden Intents abgleichen und validieren oder sogar Stub-Antworten anstelle von tatsächlichen Intent-Antworten bereitstellen.

Einstellungen für Apps und Dienste:
  • CarrierConfig
  • Notfallinformationen
  • OneTimeInitializer
  • PhotoTable (Bildschirmschoner)
  • Bereitstellung
  • Einstellungen
  • Speichermanager
  • Telefonie-APN-Konfiguration
  • Hintergrund Zuschneiden
  • Hintergrundauswahl
Diese Apps bieten Endnutzern eine grafische Benutzeroberfläche, über die sie Plattformeinstellungen ändern, ihr Gerät einrichten oder den Gerätespeicher verwalten können. Automatisierte Tests auf App-Ebene sind in der Regel nicht möglich.


Hinweis: Der Einstellungsanbieter ist im ATD-Image weiterhin verfügbar.

SystemUI Ihre automatisierten Tests sollten sich auf die Logik Ihrer eigenen App konzentrieren und gleichzeitig davon ausgehen, dass andere Apps oder die Plattform ordnungsgemäß funktionieren.
AOSP-Apps und -Dienste:
  • Browser2
  • Kalender
  • Camera2
  • Kontakte
  • Telefon
  • Schreibtischuhr
  • Galerie2
  • Lateinamerikanisch
  • Launcher3QuickStep
  • Musik
  • QuickSearchBox
  • Intelligente Einstellungen
Diese Anwendungen und Dienste fallen in der Regel nicht in den Bereich der automatischen Tests für Ihren Anwendungscode.

Firebase Test Lab-Geräte verwenden

Wenn Sie Gradle-verwaltete Geräte verwenden, können Sie Ihre automatisierten instrumentierten Tests in großem Umfang auf Firebase Test Lab-Geräten ausführen. Mit Test Lab können Sie Ihre Tests gleichzeitig auf einer Vielzahl von physischen und virtuellen Android-Geräten ausführen. Diese Tests werden in Remote-Rechenzentren von Google ausgeführt. Mit der Unterstützung von Gradle-verwalteten Geräten kann das Build-System laufende Tests für diese Test Lab-Geräte basierend auf Ihren Konfigurationen vollständig verwalten.

Erste Schritte

In den folgenden Schritten wird beschrieben, wie Sie Firebase Test Lab-Geräte mit Gradle-verwalteten Geräten verwenden. Beachten Sie, dass bei diesen Schritten die Nutzeranmeldedaten über die gcloud CLI bereitgestellt werden. Dies gilt möglicherweise nicht für alle Entwicklungsumgebungen. Weitere Informationen dazu, welcher Authentifizierungsprozess für Ihre Anforderungen zu verwenden ist, finden Sie unter Funktionsweise von Standardanmeldedaten für Anwendungen.

  1. Rufen Sie die Firebase Console auf, um ein Firebase-Projekt zu erstellen. Klicken Sie auf Projekt hinzufügen und folgen Sie den Aufforderungen auf dem Bildschirm, um ein Projekt zu erstellen. Merken Sie sich Ihre Projekt-ID.

  2. Führen Sie die Schritte unter gcloud CLI installieren aus, um die Google Cloud CLI zu installieren.

  3. Konfigurieren Sie Ihre lokale Umgebung.

    1. Erstellen Sie eine Verknüpfung zu Ihrem Firebase-Projekt in gcloud:

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. Autorisieren Sie die Verwendung Ihrer Nutzeranmeldedaten für den API-Zugriff. Wir empfehlen die Autorisierung. Dazu übergeben Sie eine JSON-Datei für das Dienstkonto mithilfe von DSL im Build-Script auf Modulebene an Gradle:

      Kotlin

      firebaseTestLab {
        ...
        serviceAccountCredentials.set(file(SERVICE_ACCOUNT_JSON_FILE))
      }
      

      Groovig

      firebaseTestLab {
        ...
        serviceAccountCredentials = file(SERVICE_ACCOUNT_JSON_FILE)
      }
      

      Alternativ können Sie mit dem folgenden Terminalbefehl eine manuelle Autorisierung ausführen:

      gcloud auth application-default login
      
    3. Optional: Fügen Sie Ihr Firebase-Projekt als Kontingentprojekt hinzu. Dieser Schritt ist nur erforderlich, wenn Sie das kostenlose Kontingent für Test Lab überschreiten.

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
  4. Aktivieren Sie die erforderlichen APIs.

    Aktivieren Sie auf der Seite „API-Bibliothek“ der Google Developers Console die Cloud Testing API und die Cloud Tool Results API. Geben Sie dazu die Namen der entsprechenden APIs in das Suchfeld oben in der Console ein und klicken Sie dann auf der Übersichtsseite der einzelnen APIs auf API aktivieren.

  5. Android-Projekt konfigurieren

    1. Fügen Sie das Firebase Test Lab-Plug-in in das Build-Skript der obersten Ebene ein:

      Kotlin

      plugins {
        ...
        id("com.google.firebase.testlab") version "0.0.1-alpha05" apply false
      }
      

      Groovig

      plugins {
        ...
        id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false
      }
      
    2. Aktivieren Sie benutzerdefinierte Gerätetypen in der Datei gradle.properties:

      android.experimental.testOptions.managedDevices.customDevice=true
      
    3. Fügen Sie das Firebase Test Lab-Plug-in dem Build-Skript auf Modulebene hinzu:

      Kotlin

      plugins {
       ...
       id "com.google.firebase.testlab"
      }
      

      Groovig

      plugins {
       ...
       id 'com.google.firebase.testlab'
      }
      

Test Lab-Gerät angeben

Sie können im Build-Skript auf Modulebene ein Firebase Test Lab-Gerät für Gradle angeben, das zum Testen Ihrer App verwendet wird. Mit dem folgenden Codebeispiel wird ein Pixel 3 mit API-Level 30 als von Gradle verwaltetes Test Lab-Gerät namens ftlDevice erstellt. Der Block firebaseTestLab {} ist verfügbar, wenn Sie das Plug-in com.google.firebase.testlab auf Ihr Modul anwenden.

Kotlin

firebaseTestLab {
  managedDevices {
    create("ftlDevice") {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Groovig

firebaseTestLab {
  managedDevices {
    ftlDevice {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Informationen zum Definieren einer Gruppe von Gradle-verwalteten Geräten, einschließlich Firebase Test Lab-Geräten, finden Sie unter Gerätegruppen definieren.

Verwende zum Ausführen der Tests dieselben Befehle wie andere von Gradle verwaltete Geräte. Gradle führt keine Tests parallel aus und unterstützt keine anderen Google Cloud CLI-Konfigurationen für Test Lab-Geräte.

Testläufe mit intelligenter Fragmentierung optimieren

Tests auf Gradle-verwalteten Test Lab-Geräten unterstützen die intelligente Fragmentierung. Durch die intelligente Fragmentierung werden Ihre Tests automatisch auf Shards verteilt, sodass jeder Shard ungefähr zur gleichen Zeit ausgeführt wird. Dadurch wird der manuelle Zuweisungsaufwand und die gesamte Testlaufdauer reduziert. Bei der intelligenten Fragmentierung werden der Testverlauf oder Informationen darüber, wie lange die vorherige Ausführung von Tests gedauert hat, verwendet, um Tests optimal zu verteilen. Sie benötigen Version 0.0.1-alpha05 des Gradle-Plug-ins für Firebase Test Lab, um die intelligente Fragmentierung zu verwenden.

Um die intelligente Fragmentierung zu aktivieren, geben Sie die Zeit an, die Tests innerhalb jedes Shards in Anspruch nehmen sollen. Sie sollten die Dauer der Ziel-Shard-Zeit auf mindestens fünf Minuten unter timeoutMinutes festlegen, um zu vermeiden, dass Shards abgebrochen werden, bevor die Tests beendet werden können.

firebaseTestLab {
  ...
  testOptions {
    targetedShardDurationMinutes = 2
  }
}

Weitere Informationen finden Sie unter DSL-Optionen für Firebase Test Lab-Geräte.

DSL für Test Lab-Geräte aktualisiert

Es gibt weitere DSL-Optionen, die Sie konfigurieren können, um Ihre Testläufe anzupassen oder von anderen Lösungen zu migrieren, die Sie möglicherweise bereits verwenden. Einige dieser Optionen werden im folgenden Code-Snippet beschrieben.

firebaseTestLab {
  ...

  /**
   * A path to a JSON file that contains service account credentials to access to
   * a Firebase Test Lab project.
   */
  serviceAccountCredentials.set(file("your_service_account_credentials.json"))


  testOptions {
    fixture {
      /**
       * Whether to grant permissions on the device before tests begin.
       * Available options are "all" or "none".
       *
       * Default value is "all".
       */
      grantedPermissions = "all"

      /**
       * Map of files to push to the device before starting the test.
       *
       * The key is the location on the device.
       * The value is the location of the file, either local or in Google Cloud.
       */
      extraDeviceFiles["/sdcard/dir1/file1.txt"] = "local/file.txt"
      extraDeviceFiles["/sdcard/dir2/file2.txt"] = "gs://bucket/file.jpg"

      /**
       * The name of the network traffic profile.
       *
       * Specifies network conditions to emulate when running tests.
       *
       * Default value is empty.
       */
      networkProfile = "LTE"
    }

    execution {
      /**
       * The maximum time to run the test execution before cancellation,
       * measured in minutes. Does not include the setup or teardown of device,
       * and is handled server-side.
       *
       * The maximum possible testing time is 45 minutes on physical devices
       * and 60 minutes on virtual devices.
       *
       * Defaults to 15 minutes.
       */
       timeoutMinutes = 30

      /**
       * Number of times the test should be rerun if tests fail.
       * The number of times a test execution should be retried if one
       * or more of its test cases fail.
       *
       * The max number of times is 10.
       *
       * The default number of times is 0.
       */
      maxTestReruns = 2

      /**
       * Ensures only a single attempt is made for each execution if
       * an infrastructure issue occurs. This doesn't affect `maxTestReruns`.
       * Normally, two or more attempts are made by Firebase Test Lab if a
       * potential infrastructure issue is detected. This is best enabled for
       * latency sensitive workloads. The number of execution failures might be
       * significantly greater with `failFast` enabled.
       *
       * Defaults to false.
       */
      failFast = false

      /**
       * The number of shards to split the tests across.
       *
       * Default to 0 for no sharding.
       */
      numUniformShards = 20
    }

    /**
     * For smart sharding, the target length of time each shard should takes in
     * minutes. Maxes out at 50 shards for physical devices and 100 shards for
     * virtual devices.
     *
     * Only one of numUniformShards or targetedShardDurationMinutes can be set.
     *
     * Defaults to 0 for no smart sharding.
     */
     targetedShardDurationMinutes = 15
    }

    results {
      /**
       * The name of the Google storage bucket to store the test results in.
       *
       * If left unspecified, the default bucket is used.
       *
       * Please refer to Firebase Test Lab permissions for required permissions
       * for using the bucket.
       */
      cloudStorageBucket = "bucketLocationName"

      /**
       * Name of test results for the Firebase console history list.
       * All tests results with the same history name are grouped
       * together in the Firebase console in a time-ordered test history list.
       *
       * Defaults to the application label in the APK manifest in Flank/Fladle.
       */
      resultsHistoryName = "application-history"

      /**
       * List of paths to copy from the test device's storage to the test
       * results folder. These must be absolute paths under /sdcard or
       * /data/local/tmp.
       */
      directoriesToPull.addAll(
        "/sdcard/path/to/something"
      )

      /**
       * Whether to enable video recording during the test.
       *
       * Disabled by default.
       */
      recordVideo = false

      /**
       * Whether to enable performance metrics. If enabled, monitors and records
       * performance metrics such as CPU, memory, and network usage.
       *
       * Defaults to false.
       */
      performanceMetrics = true
  }
}