Scala i tuoi test con i dispositivi gestiti da Gradle

I dispositivi gestiti da Gradle migliorano coerenza, prestazioni e affidabilità per i test strumentati automatizzati. Questa funzionalità, disponibile per i livelli API 27 e successivi, consente di configurare dispositivi di test fisici virtuali o remoti nei file Gradle del progetto. Il sistema di build utilizza le configurazioni per gestire completamente (ovvero creare, eseguire il deployment ed eliminare i dispositivi) durante l'esecuzione dei test automatici.

Questa funzionalità garantisce a Gradle visibilità non solo sui test in esecuzione, ma anche sul ciclo di vita dei dispositivi, migliorando così la qualità dell'esperienza di test nei seguenti modi:

  • Gestisce i problemi relativi ai dispositivi per garantire l'esecuzione dei test
  • Per i dispositivi virtuali, utilizza snapshot di emulatori per migliorare i tempi di avvio e l'utilizzo della memoria, nonché per ripristinare lo stato di pulizia dei dispositivi tra un test e l'altro
  • Memorizza nella cache i risultati dei test ed esegue solo i test che potrebbero fornire risultati diversi
  • Fornisce un ambiente coerente per l'esecuzione dei test tra esecuzioni di test locali e remoti

Creare un dispositivo virtuale gestito da Gradle

Puoi specificare un dispositivo virtuale che vuoi che Gradle utilizzi per testare la tua app nel file di build a livello di modulo. Il seguente esempio di codice crea un Pixel 2 con livello API 30 come dispositivo gestito da Gradle.

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

Trendy

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

Definisci gruppi di dispositivi

Per scalare i tuoi test su più configurazioni di dispositivi, ad esempio diversi livelli API e fattori di forma, puoi definire più dispositivi gestiti da Gradle e aggiungerli a un gruppo denominato. Gradle può eseguire i test su tutti i dispositivi del gruppo in parallelo.

L'esempio seguente mostra due dispositivi aggiunti a un gruppo di dispositivi chiamato phoneAndTablet.

Kotlin

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

Trendy

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

Esegui i test

Per eseguire i test utilizzando i dispositivi gestiti da Gradle che hai configurato, utilizza il comando seguente. device-name è il nome del dispositivo configurato nello script di build Gradle (ad esempio pixel2api30) e BuildVariant è la variante di build dell'app che vuoi testare.

Su Windows:

gradlew device-nameBuildVariantAndroidTest

In Linux o macOS:

./gradlew device-nameBuildVariantAndroidTest

Per eseguire i test su un gruppo di dispositivi gestiti da Gradle, utilizza i comandi seguenti.

Su Windows:

gradlew group-nameGroupBuildVariantAndroidTest

In Linux o macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

L'output di test include un percorso a un file HTML che contiene il report del test. Puoi anche importare i risultati dei test in Android Studio per ulteriori analisi facendo clic su Esegui > Cronologia dei test nell'IDE.

Abilita sharding di test

I dispositivi gestiti da Gradle supportano lo sharding di test, che consente di suddividere la suite di test in una serie di istanze di dispositivi virtuali identiche, chiamate shard, che vengono eseguite in parallelo. L'utilizzo dello sharding dei test può aiutare a ridurre i tempi di esecuzione complessivi del test, a scapito delle risorse di calcolo aggiuntive.

Per impostare il numero di shard da utilizzare in una determinata esecuzione di test, imposta quanto segue nel file gradle.properties:

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

Quando esegui i test utilizzando questa opzione, i dispositivi gestiti da Gradle eseguono il provisioning del numero di shard specificato per ogni profilo del dispositivo nell'esecuzione del test. Ad esempio, se hai eseguito il deployment dei test su un gruppo di tre dispositivi e hai impostato numManagedDeviceShards su due, i dispositivi gestiti da Gradle eseguiranno il provisioning di un totale di sei dispositivi virtuali per l'esecuzione del test.

Al termine dei test, Gradle restituisce i risultati del test in un file .proto per ogni shard utilizzato nell'esecuzione del test.

Usa dispositivi di test automatici

I dispositivi gestiti da Gradle supportano un tipo di dispositivo emulatore denominato Dispositivo di test automatico (ATD), ottimizzato per ridurre le risorse di CPU e memoria durante l'esecuzione dei test strumentati. Gli ATD migliorano le prestazioni di runtime in diversi modi:

  • Rimuovi le app preinstallate che in genere non sono utili per testare la tua app
  • Disattiva alcuni servizi in background, che in genere non sono utili per testare l'app
  • Disattiva rendering hardware

Prima di iniziare, assicurati di aggiornare Android Emulator all'ultima versione disponibile. Quindi, specifica un'immagine "-atd" quando definisci un dispositivo gestito da Gradle nel file di build a livello di modulo, come mostrato di seguito:

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

Trendy

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

Puoi anche creare gruppi di dispositivi come per gli altri dispositivi gestiti da Gradle. Per sfruttare ulteriormente i miglioramenti delle prestazioni, puoi anche utilizzare gli ATD con partizionamento orizzontale di test per ridurre il tempo totale di esecuzione del test della tua suite di test.

Che cosa viene rimosso dalle immagini ATD?

Oltre a operare in modalità headless, gli ATD ottimizzano anche le prestazioni rimuovendo o disattivando app e servizi che in genere non sono necessari per testare il codice della tua app. La tabella che segue fornisce una panoramica dei componenti che abbiamo rimosso o disattivato nelle immagini ATD, nonché descrizioni del motivo per cui potrebbero non essere utili.

Che cosa viene rimosso nelle immagini ATD Perché potrebbe non servirti questa funzionalità durante l'esecuzione di test automatici
App dei prodotti Google:
  • Email
  • Maps
  • Chrome
  • Messaggi
  • Play Store e altri
I test automatici dovrebbero concentrarsi sulla logica della tua app, supponendo che altre app o la piattaforma funzionino correttamente.

Con Espresso-Intent, puoi associare e convalidare i tuoi intent in uscita o anche fornire risposte stub al posto di quelle effettive.

Impostazioni di app e servizi:
  • Configurazione operatore
  • InformazioniEmergenze
  • Inizializzatore OneTime
  • PhotoTable (schermi)
  • Provisioning
  • App Impostazioni
  • Gestore archiviazione
  • Configurazione APN di telefonia
  • Ritaglia sfondo
  • Selettore sfondo
Queste app presentano una GUI che consente agli utenti finali di modificare le impostazioni della piattaforma, configurare il dispositivo o gestire lo spazio di archiviazione del dispositivo. In genere, non rientra nell'ambito dei test automatici a livello di app.


Nota: il provider di impostazioni è ancora disponibile nell'immagine ATD.

SystemUI I test automatici dovrebbero concentrarsi sulla logica della tua app, supponendo che altre app o la piattaforma funzionino correttamente.
App e servizi AOSP:
  • Browser2
  • Calendario
  • Camera2
  • Contatti
  • Telefono
  • Orologio da tavolo
  • Galleria 2
  • latinoamericano
  • Avvio rapido 3
  • Musica
  • Casella di ricerca rapida
  • Intelligence delle impostazioni
In genere, queste app e questi servizi non rientrano nell'ambito dei test automatici per il codice della tua app.

Utilizza dispositivi Firebase Test Lab

Puoi eseguire test strumentati automatizzati su larga scala sui dispositivi Firebase Test Lab quando utilizzi i dispositivi gestiti da Gradle. Test Lab consente di eseguire i test in simultanea su un'ampia gamma di dispositivi Android, sia fisici che virtuali. Questi test vengono eseguiti in data center remoti di Google. Con il supporto dei dispositivi gestiti da Gradle, il sistema di build può gestire completamente i test in esecuzione su questi dispositivi Test Lab in base alle tue configurazioni.

Inizia

I passaggi seguenti descrivono come iniziare a utilizzare i dispositivi Firebase Test Lab con i dispositivi gestiti da Gradle. Tieni presente che questi passaggi utilizzano gcloud CLI per fornire le credenziali utente, che potrebbero non essere applicabili a tutti gli ambienti di sviluppo. Per ulteriori informazioni sul processo di autenticazione da utilizzare per le tue esigenze, vedi Come funzionano le credenziali predefinite dell'applicazione.

  1. Per creare un progetto Firebase, vai alla console di Firebase. Fai clic su Aggiungi progetto e segui le istruzioni sullo schermo per creare un progetto. Ricorda l'ID progetto.

  2. Per installare Google Cloud CLI, segui i passaggi descritti in Installare gcloud CLI.

  3. Configura il tuo ambiente locale.

    1. Collega al tuo progetto Firebase in gcloud:

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. Autorizza l'utilizzo delle tue credenziali utente per l'accesso all'API. Ti consigliamo di eseguire l'autorizzazione passando un file JSON dell'account di servizio a Gradle utilizzando la DSL nello script di build a livello di modulo:

      Kotlin

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

      Trendy

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

      In alternativa, puoi autorizzarli manualmente utilizzando il seguente comando del terminale:

      gcloud auth application-default login
      
    3. (Facoltativo) Aggiungi il progetto Firebase come progetto della quota. Questo passaggio è necessario solo se superi la quota senza costi per Test Lab.

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
  4. Abilita le API richieste.

    Nella pagina della libreria API di Google Developers Console, abilita l'API Cloud Testing e l'API Cloud Tool Results digitando i nomi delle API nella casella di ricerca nella parte superiore della console, quindi facendo clic su Abilita API nella pagina Panoramica di ogni API.

  5. Configura il tuo progetto Android.

    1. Aggiungi il plug-in Firebase Test Lab nello script di build di primo livello:

      Kotlin

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

      Trendy

      plugins {
        ...
        id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false
      }
      
    2. Attiva tipi di dispositivi personalizzati nel file gradle.properties:

      android.experimental.testOptions.managedDevices.customDevice=true
      
    3. Aggiungi il plug-in Firebase Test Lab nello script di build a livello di modulo:

      Kotlin

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

      Trendy

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

Specifica un dispositivo Test Lab

Puoi specificare un dispositivo Firebase Test Lab per Gradle da utilizzare per testare la tua app nello script di build a livello di modulo. Il seguente esempio di codice crea un Pixel 3 con livello API 30 come dispositivo Test Lab gestito da Gradle chiamato ftlDevice. Il blocco firebaseTestLab {} è disponibile quando applichi il plug-in com.google.firebase.testlab al modulo.

Kotlin

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

Trendy

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

Per definire un gruppo di dispositivi gestiti da Gradle, inclusi i dispositivi Firebase Test Lab, consulta Definire gruppi di dispositivi.

Per eseguire i test, utilizza gli stessi comandi utilizzati per eseguire altri dispositivi gestiti da Gradle. Tieni presente che Gradle non esegue test in parallelo né supporta altre configurazioni di Google Cloud CLI per i dispositivi Test Lab.

Ottimizza le esecuzioni di test con lo sharding intelligente

I test su dispositivi Test Lab gestiti da Gradle supportano lo sharding intelligente. Lo sharding intelligente distribuisce automaticamente i tuoi test tra gli shard in modo che ciascuno venga eseguito all'incirca allo stesso tempo, riducendo gli sforzi di allocazione manuale e la durata complessiva dell'esecuzione dei test. Lo sharding intelligente utilizza la cronologia dei test o le informazioni sul tempo impiegato in precedenza per l'esecuzione dei test, al fine di distribuire i test in modo ottimale. Tieni presente che è necessaria la versione 0.0.1-alpha05 del plug-in Gradle affinché Firebase Test Lab possa utilizzare lo sharding intelligente.

Per abilitare lo sharding intelligente, specifica la quantità di tempo che devono essere necessari per i test all'interno di ogni shard. Devi impostare la durata del tempo di shard target su almeno cinque minuti rispetto a timeoutMinutes per evitare la situazione in cui gli shard vengono annullati prima del termine dei test.

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

Per saperne di più, consulta le opzioni DSL dei dispositivi Firebase Test Lab.

DSL aggiornata per i dispositivi Test Lab

Esistono altre opzioni DSL che puoi configurare per personalizzare le esecuzioni di test o per eseguire la migrazione da altre soluzioni che potresti già utilizzare. Vedi alcune di queste opzioni come descritto nel seguente snippet di codice.

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