Это краткое введение в сопоставление тестов и объяснение того, как начать настройку тестов в проекте Android Open Source Project (AOSP).
О сопоставлении тестов
Метод сопоставления тестов — это подход на основе Gerrit, который позволяет разработчикам создавать правила тестирования до и после отправки изменений непосредственно в исходном коде Android, оставляя решения о ветвях и тестируемых устройствах тестовой инфраструктуре. Определения сопоставления тестов представляют собой JSON-файлы с именем TEST_MAPPING , которые можно разместить в любом каталоге исходного кода.
Atest может использовать файлы TEST_MAPPING для запуска предварительных тестов перед отправкой в соответствующих каталогах. С помощью сопоставления тестов можно добавить один и тот же набор тестов в предварительные проверки с минимальными изменениями в исходном коде Android.
Посмотрите эти примеры:
Добавьте тесты перед отправкой в переменную
TEST_MAPPINGдляservices.coreДобавьте тесты перед отправкой в
TEST_MAPPINGдляtools/dexterиспользуя импорт.
В основе метода сопоставления тестов лежит использование тестовой среды Торговой федерации (TF) для выполнения тестов и формирования отчетов о результатах.
Определить тестовые группы
Функция сопоставления тестов объединяет тесты в группу тестов . Название группы тестов может быть любой строкой. Например, presubmit может быть названием группы тестов, которые будут запускаться при проверке изменений. А postsubmit может быть названием тестов, используемых для проверки сборок после слияния изменений.
правила скрипта сборки пакета
Для того чтобы тестовая среда Trade Federation могла запускать тестовые модули для данной сборки, эти модули должны иметь параметр test_suites установленный для Soong , или параметр LOCAL_COMPATIBILITY_SUITE , установленный для Make, на один из этих двух наборов тестов:
-
general-testsпредназначен для тестов, которые не зависят от специфических возможностей устройства (например, от оборудования конкретного производителя, которого нет у большинства устройств). Большинство тестов должны быть включены в пакетgeneral-tests, даже если они специфичны для одного ABI, разрядности или аппаратных функций, таких как HWASan (для каждого ABI существует отдельный целевой объектtest_suites), и даже если они должны выполняться на устройстве. -
device-testsпредназначен для тестов, зависящих от возможностей конкретного устройства. Обычно такие тесты находятся в папкеvendor/. Device-specific относится только к возможностям, уникальным для данного устройства, поэтому это относится как к тестам 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"/>
Создайте тестовые файлы сопоставления.
Для каталога, требующего проверки покрытия тестами, добавьте JSON-файл TEST_MAPPING аналогичный приведенному примеру . Эти правила гарантируют, что тесты будут запускаться в рамках предварительных проверок перед отправкой, когда в этом каталоге или любом из его подкаталогов будут изменены какие-либо файлы.
Следуйте примеру
Вот пример файла 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": "CtsDeqpTestCases",
"options": [
{
// Use regex in include-filter which is supported in AndroidJUnitTest
"include-filter": "dEQP-EGL.functional.color_clears.*"
}
]
}
],
"imports": [
{
"path": "frameworks/base/services/core/java/com/android/server/am"
}
]
}
Установить атрибуты
В приведенном примере presubmit и postsubmit — это названия каждой тестовой группы. Дополнительную информацию о тестовых группах см. в разделе «Определение тестовых групп».
В значении атрибута name можно задать имя тестового модуля или имя интеграционного теста Trade Federation (например, путь к XML-файлу теста, uiautomator/uiautomator-demo ). Обратите внимание, что в поле name нельзя использовать name класса или name тестового метода. Чтобы сузить круг запускаемых тестов, используйте такие параметры, как include-filter . См. пример использования include-filter .
Параметр host теста указывает, является ли тест беспроводным и выполняется ли он на хосте или нет. Значение по умолчанию — false , что означает, что для выполнения теста требуется устройство. Поддерживаются следующие типы тестов: HostGTest для бинарных файлов GTest и HostTest для тестов JUnit.
Атрибут file_patterns позволяет задать список строк регулярных выражений для сопоставления относительного пути к любому файлу исходного кода (относительно каталога, содержащего файл TEST_MAPPING ). В примере тест CtsWindowManagerDeviceTestCases запускается в режиме presubmit только тогда, когда файл Java начинается с Window или Activity и находится в том же каталоге, что и файл TEST_MAPPING или в любом из его подкаталогов. Обратные косые черты (\) необходимо экранировать, поскольку они находятся в файле JSON.
Атрибут imports позволяет включать тесты в другие файлы TEST_MAPPING без копирования их содержимого. Файлы TEST_MAPPING находящиеся в родительских каталогах импортируемого пути, также включаются. Функция сопоставления тестов допускает вложенный импорт; это означает, что два файла TEST_MAPPING могут импортировать друг друга, а сопоставление тестов может объединять включенные тесты.
Атрибут options содержит дополнительные параметры командной строки Tradefed.
Чтобы получить полный список доступных опций для данного теста, выполните следующую команду:
tradefed.sh run commandAndExit [test_module] --help
Для получения более подробной информации о том, как работают опционы, обратитесь к разделу «Обработка опционов в Tradefed» .
Проверки TEST_MAPPING
При отправке изменений, затрагивающих файлы TEST_MAPPING , перед отправкой выполняются проверки для обеспечения корректности:
- Проверка шаблонов файлов: гарантирует, что все регулярные выражения в
file_patternsсоответствуют хотя бы одному файлу в репозитории. Устаревшие шаблоны, не соответствующие ни одному файлу, приводят к сбою проверки. - Проверка во время сборки: Преобразует предупреждения, собранные в процессе сборки, в критические ошибки на этапе подготовки к отправке для основных веток. К распространенным предупреждениям относятся:
- Несуществующие модули: ссылка на имя тестового модуля, которого нет в кодовой базе, например, если в имени допущена опечатка.
- Недопустимые импорты: В
importsсодержатся ссылки на пути, которые не существуют или не содержат файлTEST_MAPPING. - Проблемы со схемой: использование неподдерживаемых ключей или некорректных структур в конфигурации JSON.
Запускайте тесты с помощью Atest
Для локального выполнения правил предварительного тестирования:
- Перейдите в каталог, содержащий файл
TEST_MAPPING. Выполните команду:
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
Запустите правила тестирования после отправки формы.
Вы также можете использовать эту команду для запуска правил тестирования postsubmit, определенных в TEST_MAPPING в src_path (по умолчанию — текущий рабочий каталог) и его родительских каталогах:
atest [--test-mapping] [src_path]:postsubmit
Запускайте только те тесты, которые не требуют наличия устройства.
Для запуска тестов в Atest можно использовать опцию --host , чтобы выполнять только те тесты, которые настроены для хоста, не требующего устройства. Без этой опции Atest запускает оба типа тестов: те, которые требуют устройства, и те, которые выполняются на хосте, не требующем устройства. Тесты запускаются в двух отдельных наборах:
atest [--test-mapping] --host
Определить тестовые группы
В команде Atest можно указать группы тестов. Следующая команда запускает все тесты, postsubmit , относящиеся к файлам в каталоге 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-subdir Atest запускает только тест A. С опцией --include-subdir Atest запускает два теста (A, B).
Поддерживаются комментарии на уровне строки.
Вы можете добавить построчный комментарий // format, чтобы дополнить файл TEST_MAPPING описанием следующей за ним настройки. ATest and Trade Federation предварительно обрабатывает файл TEST_MAPPING преобразуя его в допустимый формат JSON без комментариев. Для сохранения чистоты файла JSON поддерживается только построчный комментарий // format.
Пример:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}