Тестовое картирование

Это краткое введение в Test Mapping и объяснение того, как легко приступить к настройке тестов в Android Open Source Project (AOSP).

Что такое тестовое картирование?

Test Mapping — это подход, основанный на Gerrit, который позволяет разработчикам создавать правила тестирования до и после отправки непосредственно в дереве исходного кода Android и оставлять решения о тестировании веток и устройств самой тестовой инфраструктуре. Определения тестового сопоставления представляют собой файлы JSON с именем TEST_MAPPING, которые можно поместить в любой исходный каталог.

Atest может использовать файлы TEST_MAPPING для запуска предварительных тестов в соответствующих каталогах. С помощью Test Mapping вы можете добавить тот же набор тестов для предварительной проверки с помощью простого изменения в дереве исходного кода Android.

Посмотрите эти примеры:

Добавьте предварительные тесты в TEST_MAPPING для services.core.

Добавить тесты предварительной отправки в TEST_MAPPING для инструментов/декстера с использованием импорта.

Тестовое картирование использует тестовую систему Торговой федерации (TF) для выполнения тестов и отчетов о результатах.

Определение тестовых групп

Test Mapping группирует тесты через test group . Имя тестовой группы может быть любой строкой. Например, предварительная отправка может использоваться для запуска группы тестов при проверке изменений. А тесты после отправки можно использовать для проверки сборок после объединения изменений.

Правила скрипта сборки упаковки

Чтобы тестовая система Trade Federation Test Harness могла запускать тестовые модули Test Mapping для данной сборки, эти модули должны иметь test_suite , установленный для Soong , или LOCAL_COMPATIBILITY_SUITE , установленный для Make для одного из этих двух наборов:

  • общие-тесты — тесты, которые не зависят от функциональности конкретного устройства (например, аппаратного обеспечения конкретного поставщика, которого нет у большинства устройств). Большинство тестов должны быть в наборе общих тестов, даже если они специфичны для одного ABI, разрядности или аппаратных функций, таких как HWASan (для каждого ABI существует отдельная цель test_suites), и даже если они должны выполняться на устройстве.
  • тесты устройства — тесты, которые зависят от функциональности устройства. Обычно эти тесты можно найти в vendor/ . Поскольку «зависимость от устройства» не относится к функциям ABI или SoC, которые могут быть или не быть у других устройств, а только к функциям, уникальным для устройства, это применимо к тестам JUnit в той же степени, что и к собственным тестам GTest (которые обычно должны быть general-tests даже если они специфичны для ABI).

Примеры:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

Настройка тестов для запуска в наборе тестов

Чтобы тест выполнялся внутри набора тестов, тест:

  • не должен иметь провайдера сборки.
  • должен очиститься после его завершения, например, удалив все временные файлы, созданные во время теста.
  • изменить системные настройки на значения по умолчанию или исходное значение.
  • не следует предполагать, что устройство находится в определенном состоянии, например готово для получения root-прав. Для запуска большинства тестов не требуются привилегии root. Если для теста требуется root, он должен указать это с помощью RootTargetPreparer в своем AndroidTest.xml , как в следующем примере:
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>

Создание тестовых файлов сопоставления

Для каталога, требующего тестового покрытия, просто добавьте файл TEST_MAPPING JSON, подобный приведенному ниже примеру. Эти правила гарантируют, что тесты будут выполняться в проверках перед отправкой, когда затрагиваются какие-либо файлы в этом каталоге или любом из его подкаталогов.

Следуя примеру

Вот пример файла TEST_MAPPING (в формате JSON, но с поддержкой комментариев):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsWindowManagerDeviceTestCases"
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Установка атрибутов

В приведенном выше примере presubmit и postsubmit — это названия каждой тестовой группы . Дополнительные сведения о группах тестов см. в разделе Определение групп тестов.

Имя тестового модуля или имя теста интеграции Торговой федерации (путь ресурса к тестовому XML-файлу, например, uiautomator/uiautomator-demo ) может быть задано в значении атрибута name . Обратите внимание, что в поле имени нельзя использовать name класса или name метода тестирования. Чтобы сузить тесты для запуска, вы можете использовать такие параметры, как include-filter здесь. См. ( пример использования include-filter ).

Параметр хоста теста указывает, является ли тест тестом без устройств, выполняемым на хосте, или нет. Значение по умолчанию — false , что означает, что для запуска теста требуется устройство. Поддерживаемые типы тестов: HostGTest для двоичных файлов GTest и HostTest для тестов JUnit.

Атрибут file_patterns позволяет вам установить список строк регулярных выражений для сопоставления относительного пути любого файла исходного кода (относительно каталога, содержащего файл TEST_MAPPING). В приведенном выше примере тест CtsWindowManagerDeviceTestCases будет выполняться в режиме предварительной отправки только тогда, когда любой файл Java начинается с Window или Activity, который существует в том же каталоге, что и файл TEST_MAPPING, или в любом из его подкаталогов. Обратная косая черта \ должна быть экранирована, так как она находится в файле JSON.

Атрибут imports позволяет включать тесты в другие файлы TEST_MAPPING без копирования содержимого. Обратите внимание, что файлы TEST_MAPPING в родительских каталогах импортированного пути также будут включены. Test Mapping допускает вложенный импорт; это означает, что два файла TEST_MAPPING могут импортировать друг друга, а Test Mapping может правильно объединять включенные тесты.

Атрибут options содержит дополнительные параметры командной строки TradeFed.

Чтобы получить полный список доступных опций для данного теста, запустите:

tradefed.sh run commandAndExit [test_module] --help

Обратитесь к Обработке опционов TradeFed для получения более подробной информации о том, как работают опционы.

Запуск тестов с Atest

Чтобы локально выполнить правила проверки перед отправкой:

  1. Перейдите в каталог, содержащий файл TEST_MAPPING.
  2. Запустите команду:
atest

Запускаются все предварительные тесты, настроенные в файлах TEST_MAPPING текущего каталога и его родительских каталогов. Atest найдет и запустит два теста для предварительной отправки (A и B).

Это самый простой способ запустить предварительные тесты в файлах TEST_MAPPING в текущем рабочем каталоге (CWD) и родительских каталогах. Atest найдет и будет использовать файл TEST_MAPPING в CWD и во всех его родительских каталогах.

Структурирование исходного кода

В следующем примере показано, как можно настроить файлы TEST_MAPPING в исходном дереве.

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

Содержимое src/TEST_MAPPING :

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

Содержимое src/project_1/TEST_MAPPING :

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

Содержимое src/project_2/TEST_MAPPING :

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

Указание целевых каталогов

Вы можете указать целевой каталог для запуска тестов в файлах TEST_MAPPING в этом каталоге. Следующая команда запустит два теста (A, B).

atest --test-mapping src/project_1

Запуск правил тестирования после отправки

Вы также можете использовать эту команду для запуска правил тестирования после отправки, определенных в TEST_MAPPING, в src_path (по умолчанию CWD) и его родительских каталогах:

atest [--test-mapping] [src_path]:postsubmit

Выполнение только тестов, не требующих устройства

Вы можете использовать параметр --host для Atest, чтобы запускать только тесты, настроенные для хоста, для которого не требуется устройство. Без этой опции Atest будет запускать оба теста: те, которые требуют устройства, и те, которые выполняются на хосте и не требуют никаких устройств. Тесты будут проводиться в двух отдельных наборах.

atest [--test-mapping] --host

Идентификация тестовых групп

Вы можете указать тестовые группы в команде Atest. Следующая команда запустит все тесты после отправки , связанные с файлами в каталоге src/project_1, который содержит только один тест (C).

Или вы можете использовать :all для запуска всех тестов независимо от группы. Следующая команда запускает четыре теста (A, B, C, X):

atest --test-mapping src/project_1:all

Включая подкаталоги

По умолчанию при запуске тестов в TEST_MAPPING с помощью Atest будут запускаться только предварительные тесты, настроенные в файле TEST_MAPPING в CWD (или заданном каталоге) и его родительских каталогах. Если вы хотите запускать тесты во всех файлах TEST_MAPPING в подкаталогах, используйте параметр --include-subdir , чтобы Atest также включил эти тесты.

atest --include-subdir

Без параметра --include --include-subdir Atest запустит только тест A. С параметром --include --include-subdir Atest запустит два теста (A, B).

Комментарий на уровне строки поддерживается

Вы можете добавить комментарий на уровне строки // в формате, чтобы дополнить файл TEST_MAPPING описанием следующей настройки. ATest и Trade Federation предварительно обработают TEST_MAPPING в допустимом формате JSON без комментариев. Чтобы сохранить файл JSON чистым и легко читаемым, поддерживаются только комментарии в // -формате строкового уровня.

Пример:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}