Масштабируйте свои тесты с помощью устройств под управлением Gradle

Устройства, управляемые Gradle, повышают согласованность, производительность и надежность автоматизированных инструментальных тестов. Эта функция, доступная для уровней API 27 и выше, позволяет настраивать виртуальные или удаленные физические тестовые устройства в файлах Gradle вашего проекта. Система сборки использует конфигурации для полного управления — то есть создания, развертывания и отключения — этими устройствами при выполнении автоматических тестов.

Эта функция позволяет Gradle видеть не только тесты, которые вы выполняете, но и жизненный цикл устройств, тем самым улучшая качество вашего тестирования следующими способами:

  • Управляет проблемами, связанными с устройством, чтобы обеспечить выполнение ваших тестов.
  • Для виртуальных устройств используются снимки эмулятора, чтобы улучшить время запуска устройства и использование памяти, а также восстановить устройства в чистое состояние между тестами.
  • Кэширует результаты тестов и повторно запускает только те тесты, которые могут дать разные результаты.
  • Обеспечивает согласованную среду для запуска тестов между локальными и удаленными запусками тестов.

Создайте виртуальное устройство, управляемое Gradle.

Вы можете указать виртуальное устройство, которое Gradle будет использовать для тестирования вашего приложения, в файле сборки на уровне модуля. В следующем примере кода создается Pixel 2 с API уровня 30 в качестве устройства, управляемого Gradle.

Котлин

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

классный

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

Определить группы устройств

Чтобы помочь вам масштабировать тесты для нескольких конфигураций устройств, таких как различные уровни API и форм-факторы, вы можете определить несколько устройств, управляемых Gradle, и добавить их в именованную группу. Затем Gradle сможет выполнять ваши тесты на всех устройствах в группе параллельно.

В примере ниже показаны два устройства, добавленные в группу устройств под названием phoneAndTablet .

Котлин

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

классный

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

Запустите свои тесты

Чтобы запустить тесты с использованием настроенных вами устройств, управляемых Gradle, используйте следующую команду. device-name — это имя устройства, которое вы настроили в сценарии сборки Gradle (например, pixel2api30 ), а BuildVariant — это вариант сборки вашего приложения, которое вы хотите протестировать.

В Windows:

gradlew device-nameBuildVariantAndroidTest

В Linux или macOS:

./gradlew device-nameBuildVariantAndroidTest

Чтобы запустить тесты на группе устройств, управляемых Gradle, используйте следующие команды.

В Windows:

gradlew group-nameGroupBuildVariantAndroidTest

В Linux или macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

Выходные данные теста включают путь к HTML-файлу, содержащему отчет о тестировании. Вы также можете импортировать результаты тестов в Android Studio для дальнейшего анализа, нажав «Выполнить» > «История тестов» в IDE.

Включить тестовое сегментирование

Устройства, управляемые Gradle, поддерживают сегментирование тестов, что позволяет разделить набор тестов на несколько идентичных экземпляров виртуальных устройств, называемых сегментами , которые выполняются параллельно. Использование сегментирования тестов может помочь сократить общее время выполнения теста за счет дополнительных вычислительных ресурсов.

Чтобы установить количество сегментов, которые вы хотите использовать в данном тестовом запуске, установите следующее в файле gradle.properties :

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

При запуске тестов с использованием этой опции устройства, управляемые Gradle, предоставляют количество сегментов, указанное вами для каждого профиля устройства в тестовом запуске. Так, например, если вы развернули свои тесты на группе устройств из трех устройств и установили для numManagedDeviceShards значение два, устройства, управляемые Gradle, предоставят в общей сложности шесть виртуальных устройств для вашего тестового запуска.

Когда ваши тесты завершены, Gradle выводит результаты тестов в файле .proto для каждого сегмента, использованного в тестовом запуске.

Используйте устройства автоматического тестирования

Устройства, управляемые Gradle, поддерживают тип устройства-эмулятора, называемый устройством автоматического тестирования (ATD), которое оптимизировано для сокращения ресурсов ЦП и памяти при выполнении инструментированных тестов. ATD улучшают производительность во время выполнения несколькими способами:

  • Удалите предустановленные приложения, которые обычно бесполезны для тестирования вашего приложения.
  • Отключите определенные фоновые службы, которые обычно бесполезны для тестирования вашего приложения.
  • Отключить аппаратный рендеринг

Прежде чем начать, обязательно обновите эмулятор Android до последней доступной версии. Затем укажите образ «-atd» при определении устройства, управляемого Gradle, в файле сборки на уровне модуля, как показано ниже:

Котлин

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

классный

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

Вы также можете создавать группы устройств, как и другие устройства, управляемые Gradle. Чтобы еще больше повысить производительность, вы также можете использовать ATD с сегментированием тестов , чтобы сократить общее время выполнения тестов вашего набора тестов.

Что удалено из изображений ATD?

Помимо работы в автономном режиме, ATD также оптимизируют производительность, удаляя или отключая приложения и службы, которые обычно не требуются для тестирования кода вашего приложения. В таблице ниже представлен обзор компонентов, которые мы удалили или отключили в образах ATD, и описано, почему они могут оказаться бесполезными.

Что удалено из изображений ATD Почему вам это может не понадобиться при запуске автоматических тестов
Приложения продуктов Google:
  • Почта
  • Карты
  • Хром
  • Сообщения
  • Play Маркет и другие.
Ваши автоматизированные тесты должны быть сосредоточены на логике вашего собственного приложения, предполагая при этом, что другие приложения или платформа будут работать правильно.

С помощью Espresso-Intents вы можете сопоставлять и проверять свои исходящие намерения или даже предоставлять ответы-заглушки вместо фактических ответов о намерениях.

Настройки приложений и сервисов:
  • Конфигурация оператора связи
  • Чрезвычайная информация
  • Одноразовый инициализатор
  • Фотостол (заставки)
  • Обеспечение
  • Приложение настроек
  • Менеджер хранения
  • Конфигурация APN телефонии
  • ОбоиОбрезка
  • Выбор обоев
Эти приложения предоставляют конечным пользователям графический интерфейс, позволяющий изменять настройки платформы, настраивать свое устройство или управлять хранилищем устройства. Обычно это выходит за рамки автоматического тестирования на уровне приложения.


Примечание. Поставщик настроек по-прежнему доступен в образе ATD.

Системный интерфейс Ваши автоматизированные тесты должны быть сосредоточены на логике вашего собственного приложения, предполагая при этом, что другие приложения или платформа будут работать правильно.
Приложения и сервисы AOSP:
  • Браузер2
  • Календарь
  • Камера2
  • Контакты
  • номеронабиратель
  • СтолЧасы
  • Галерея2
  • LatinIME
  • Лаунчер3QuickStep
  • Музыка
  • Окно быстрого поиска
  • НастройкиИнтеллект
Эти приложения и службы обычно выходят за рамки автоматизированных тестов кода вашего приложения.

Используйте устройства Firebase Test Lab

Вы можете запускать автоматические инструментированные тесты в любом масштабе на устройствах Firebase Test Lab при использовании устройств под управлением Gradle. Test Lab позволяет запускать тесты одновременно на широком спектре устройств Android, как физических, так и виртуальных. Эти тесты проводятся в удаленных центрах обработки данных Google. Благодаря поддержке устройств, управляемых Gradle, система сборки может полностью управлять выполнением тестов на этих устройствах Test Lab на основе ваших конфигураций.

Начать

Следующие шаги описывают, как начать использовать устройства Firebase Test Lab с устройствами, управляемыми Gradle. Обратите внимание, что в этих шагах используется интерфейс командной строки gcloud для предоставления учетных данных пользователя, что может не применяться ко всем средам разработки. Дополнительные сведения о том, какой процесс аутентификации использовать для ваших нужд, см. в разделе Как работают учетные данные приложения по умолчанию .

  1. Чтобы создать проект Firebase, перейдите в консоль Firebase . Нажмите «Добавить проект» и следуйте инструкциям на экране, чтобы создать проект. Запомните свой идентификатор проекта.

  2. Чтобы установить Google Cloud CLI, выполните действия, описанные в разделе Установка gcloud CLI .

  3. Настройте локальную среду.

    1. Ссылка на ваш проект Firebase в gcloud:

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. Разрешите использование ваших учетных данных пользователя для доступа к API. Мы рекомендуем авторизоваться, передав JSON-файл сервисной учетной записи в Gradle с помощью DSL в скрипте сборки на уровне модуля:

      Котлин

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

      классный

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

      Альтернативно вы можете авторизоваться вручную, используя следующую команду терминала:

      gcloud auth application-default login
      
    3. Необязательно: добавьте свой проект Firebase в качестве проекта квоты. Этот шаг необходим только в том случае, если вы превысите бесплатную квоту для Test Lab .

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
  4. Включите необходимые API.

    На странице библиотеки API консоли Google Developers включите Cloud Testing API и Cloud ToolResults API, введя имена этих API в поле поиска в верхней части консоли, а затем нажав «Включить API» на странице обзора для каждого API.

  5. Настройте свой Android-проект.

    1. Добавьте плагин Firebase Test Lab в скрипт сборки верхнего уровня:

      Котлин

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

      классный

      plugins {
        ...
        id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false
      }
    2. Включите пользовательские типы устройств в файле gradle.properties :

      android.experimental.testOptions.managedDevices.customDevice=true
    3. Добавьте плагин Firebase Test Lab в скрипт сборки на уровне модуля:

      Котлин

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

      классный

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

Укажите устройство тестовой лаборатории

Вы можете указать устройство Firebase Test Lab, которое Gradle будет использовать для тестирования вашего приложения, в сценарии сборки на уровне модуля. В следующем примере кода создается Pixel 3 с API-уровнем 30 в качестве управляемого Gradle устройства Test Lab под названием ftlDevice . Блок firebaseTestLab {} доступен, когда вы применяете плагин com.google.firebase.testlab к своему модулю.

Котлин

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

классный

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

Чтобы определить группу устройств, управляемых Gradle, включая устройства Firebase Test Lab, см. раздел Определение групп устройств .

Для запуска тестов используйте те же команды, которые используются для запуска других устройств, управляемых Gradle . Обратите внимание, что Gradle не запускает тесты параллельно и не поддерживает другие конфигурации Google Cloud CLI для устройств Test Lab.

Оптимизируйте тестовые прогоны с помощью интеллектуального сегментирования

Тестирование на устройствах Test Lab, управляемых Gradle, поддерживает интеллектуальное сегментирование. Интеллектуальное сегментирование автоматически распределяет ваши тесты по сегментам, так что каждый сегмент выполняется примерно одинаковое время, что сокращает усилия по ручному распределению и общую продолжительность выполнения теста. Интеллектуальное сегментирование использует историю тестов или информацию о том, сколько времени потребовалось для предыдущего выполнения тестов, для оптимального распределения тестов. Обратите внимание, что для использования интеллектуального сегментирования вам нужна версия 0.0.1-alpha05 плагина Gradle для Firebase Test Lab.

Чтобы включить интеллектуальное сегментирование, укажите количество времени, которое должно занимать тестирование внутри каждого сегмента. Вам следует установить целевую продолжительность сегментирования как минимум на пять минут меньше, чем timeoutMinutes , чтобы избежать ситуации, когда сегменты отменяются до завершения тестов.

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

Чтобы узнать больше, прочитайте о параметрах DSL для устройств Firebase Test Lab .

Обновлен DSL для устройств Test Lab.

Вы можете настроить дополнительные параметры DSL, чтобы персонализировать тестовые прогоны или перейти с других решений, которые вы, возможно, уже используете. См. некоторые из этих параметров, как описано в следующем фрагменте кода.

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