Il s'agit d'une brève introduction à Test Mapping et d'une explication sur la façon de commencer à configurer facilement des tests dans le projet Open Source Android (AOSP).
Qu'est-ce que le mappage de test ?
Test Mapping est une approche basée sur Gerrit qui permet aux développeurs de créer des règles de test avant et après la soumission directement dans l'arborescence source d'Android et de laisser les décisions des branches et des appareils à tester à l'infrastructure de test elle-même. Les définitions de mappage de test sont des fichiers JSON nommés TEST_MAPPING qui peuvent être placés dans n'importe quel répertoire source.
Atest peut utiliser les fichiers TEST_MAPPING pour exécuter des tests de pré-soumission dans les répertoires associés. Avec Test Mapping, vous pouvez ajouter le même ensemble de tests pour pré-soumettre des vérifications avec un simple changement dans l'arborescence source Android.
Voir ces exemples :
Ajouter des tests de pré-soumission à TEST_MAPPING pour services.core
Ajouter des tests de pré-soumission à TEST_MAPPING pour les outils/dexter à l'aide d'importations
La cartographie des tests s'appuie sur le harnais de test de la Fédération commerciale (TF) pour l'exécution des tests et la communication des résultats.
Définition des groupes de test
Test Mapping regroupe les tests via un groupe de tests . Le nom d'un groupe de test peut être n'importe quelle chaîne. Par exemple, la pré- soumission peut concerner un groupe de tests à exécuter lors de la validation des modifications. Et les tests post -soumission peuvent être utilisés pour valider les builds après la fusion des modifications.
Règles de script de génération d'empaquetage
Pour que Trade Federation Test Harness puisse exécuter les modules de test de Test Mapping pour une version donnée, ces modules doivent avoir test_suite défini pour Soong ou LOCAL_COMPATIBILITY_SUITE défini pour Make dans l'une de ces deux suites :
- tests généraux - tests qui ne dépendent pas des fonctionnalités spécifiques à l'appareil (comme le matériel spécifique au fournisseur que la plupart des appareils n'ont pas). La plupart des tests doivent être dans la suite de tests généraux, même s'ils sont spécifiques à un ABI ou à un bitness ou à des fonctionnalités matérielles comme HWASan (il existe une cible test_suites distincte pour chaque ABI), et même s'ils doivent s'exécuter sur un périphérique.
- device-tests - tests qui dépendent des fonctionnalités spécifiques à l'appareil. Généralement, ces tests se trouvent sous
vendor/
. Étant donné que "spécifique à l'appareil" ne fait pas référence à la fonctionnalité ABI ou SoC que d'autres appareils pourraient ou non avoir, mais uniquement à la fonctionnalité qui est unique à un appareil, cela s'applique aux tests JUnit autant qu'aux tests natifs GTest (qui devraient généralement êtregeneral-tests
même s'ils sont spécifiques à l'ABI).
Exemples:
Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests
Configuration des tests à exécuter dans une suite de tests
Pour qu'un test s'exécute dans une suite de tests, le test :
- ne doit pas avoir de fournisseur de build.
- doit nettoyer une fois qu'il est terminé, par exemple, en supprimant tous les fichiers temporaires générés pendant le test.
- modifier les paramètres système à la valeur par défaut ou d'origine.
- ne doit pas supposer qu'un périphérique est dans un certain état, par exemple, root ready. La plupart des tests ne nécessitent pas de privilège root pour s'exécuter. Si un test doit nécessiter root, il doit le spécifier avec un
RootTargetPreparer
dans sonAndroidTest.xml
, comme dans l'exemple suivant :
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
Création de fichiers de mappage de test
Pour le répertoire nécessitant une couverture de test, ajoutez simplement un fichier JSON TEST_MAPPING ressemblant à l'exemple ci-dessous. Ces règles garantiront que les tests s'exécutent dans les contrôles de pré-soumission lorsque des fichiers sont touchés dans ce répertoire ou l'un de ses sous-répertoires.
A la suite d'un exemple
Voici un exemple de fichier TEST_MAPPING
(il est au format JSON mais avec les commentaires pris en charge) :
{
"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"
}
]
}
Définition des attributs
Dans l'exemple ci-dessus, presubmit
et postsubmit
sont les noms de chaque groupe de test . Voir Définition des groupes de test pour plus d'informations sur les groupes de test.
Le nom du module de test ou le nom du test d' intégration de la fédération commerciale (chemin de ressource vers le fichier XML de test, par exemple, uiautomator/uiautomator-demo ) peut être défini dans la valeur de l'attribut name
. Notez que le champ de nom ne peut pas utiliser le name
name
la méthode de test. Pour affiner les tests à exécuter, vous pouvez utiliser des options telles que include-filter
ici. Voir ( exemple d'utilisation d'include-filtre ).
Le paramètre d' hôte d'un test indique si le test est un test sans périphérique exécuté sur l'hôte ou non. La valeur par défaut est false , ce qui signifie que le test nécessite un périphérique pour s'exécuter. Les types de test pris en charge sont HostGTest pour les binaires GTest et HostTest pour les tests JUnit.
L'attribut file_patterns vous permet de définir une liste de chaînes regex pour correspondre au chemin relatif de n'importe quel fichier de code source (par rapport au répertoire contenant le fichier TEST_MAPPING). Dans l'exemple ci-dessus, le test CtsWindowManagerDeviceTestCases
s'exécutera en pré-soumission uniquement lorsqu'un fichier Java commence par Window ou Activity, qui existe dans le même répertoire que le fichier TEST_MAPPING ou l'un de ses sous-répertoires, est modifié. Les barres obliques inverses \ doivent être échappées comme elles le sont dans un fichier JSON.
L'attribut imports vous permet d'inclure des tests dans d'autres fichiers TEST_MAPPING sans copier le contenu. Notez que les fichiers TEST_MAPPING dans les répertoires parents du chemin importé seront également inclus. Test Mapping autorise les importations imbriquées ; cela signifie que deux fichiers TEST_MAPPING peuvent s'importer et que Test Mapping est capable de fusionner correctement les tests inclus.
L'attribut options contient des options de ligne de commande TradeFed supplémentaires.
Pour obtenir une liste complète des options disponibles pour un test donné, exécutez :
tradefed.sh run commandAndExit [test_module] --help
Reportez-vous à TradeFed Option Handling pour plus de détails sur le fonctionnement des options.
Exécution de tests avec Atest
Pour exécuter localement les règles de test de pré-soumission :
- Accédez au répertoire contenant le fichier TEST_MAPPING.
- Exécutez la commande :
atest
Tous les tests de pré-soumission configurés dans les fichiers TEST_MAPPING du répertoire courant et de ses répertoires parents sont exécutés. Atest localisera et exécutera deux tests pour la pré-soumission (A et B).
C'est le moyen le plus simple d'exécuter des tests de pré-soumission dans les fichiers TEST_MAPPING du répertoire de travail actuel (CWD) et des répertoires parents. Atest localisera et utilisera le fichier TEST_MAPPING dans CWD et tous ses répertoires parents.
Structuration du code source
L'exemple suivant montre comment les fichiers TEST_MAPPING peuvent être configurés dans l'arborescence source.
src
├── project_1
│ └── TEST_MAPPING
├── project_2
│ └── TEST_MAPPING
└── TEST_MAPPING
Contenu de src/TEST_MAPPING
:
{
"presubmit": [
{
"name": "A"
}
]
}
Contenu de src/project_1/TEST_MAPPING
:
{
"presubmit": [
{
"name": "B"
}
],
"postsubmit": [
{
"name": "C"
}
],
"other_group": [
{
"name": "X"
}
]}
Contenu de src/project_2/TEST_MAPPING
:
{
"presubmit": [
{
"name": "D"
}
],
"import": [
{
"path": "src/project_1"
}
]}
Spécification des répertoires cibles
Vous pouvez spécifier un répertoire cible pour exécuter des tests dans les fichiers TEST_MAPPING de ce répertoire. La commande suivante exécutera deux tests (A, B).
atest --test-mapping src/project_1
Exécution des règles de test post-soumission
Vous pouvez également utiliser cette commande pour exécuter les règles de test post-soumission définies dans TEST_MAPPING dans src_path
(par défaut à CWD) et ses répertoires parents :
atest [--test-mapping] [src_path]:postsubmit
Exécuter uniquement des tests qui ne nécessitent aucun appareil
Vous pouvez utiliser l'option --host pour Atest pour exécuter uniquement les tests configurés sur l'hôte qui ne nécessitent aucun périphérique. Sans cette option, Atest exécutera les deux tests, ceux nécessitant un périphérique et ceux exécutés sur l'hôte et ne nécessitant aucun périphérique. Les tests seront exécutés dans deux suites distinctes.
atest [--test-mapping] --host
Identification des groupes de test
Vous pouvez spécifier des groupes de test dans la commande Atest. La commande suivante exécutera tous les tests post-soumission liés aux fichiers du répertoire src/project_1, qui ne contient qu'un seul test (C).
Ou vous pouvez utiliser :all pour exécuter tous les tests quel que soit le groupe. La commande suivante exécute quatre tests (A, B, C, X) :
atest --test-mapping src/project_1:all
Y compris les sous-répertoires
Par défaut, l'exécution de tests dans TEST_MAPPING avec Atest n'exécutera que les tests de pré-soumission configurés dans le fichier TEST_MAPPING dans CWD (ou le répertoire donné) et ses répertoires parents. Si vous souhaitez exécuter des tests dans tous les fichiers TEST_MAPPING des sous-répertoires, utilisez l'option --include-subdir
pour forcer Atest à inclure également ces tests.
atest --include-subdir
Sans l'option --include-subdir
, Atest n'exécutera que le test A. Avec l'option --include-subdir
, Atest exécutera deux tests (A, B).
Le commentaire au niveau de la ligne est pris en charge
Vous pouvez ajouter un commentaire au format //
au niveau de la ligne pour étoffer le fichier TEST_MAPPING avec une description du paramètre qui suit. ATest et Trade Federation prétraiteront le TEST_MAPPING dans un format JSON valide sans commentaires. Pour garder le fichier JSON propre et facile à lire, seuls les commentaires //
au format de ligne sont pris en charge.
Exemple:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}