Tester le mappage

Il s'agit d'une brève présentation du mappage de test et d'une explication de la façon de commencer à configurer facilement des tests dans le projet Android Open Source (AOSP).

À propos du mappage test

Le mappage de test est une approche basée sur Gerrit qui permet aux développeurs de créer des règles de test avant et après l'envoi directement dans l'arborescence source Android, et de laisser les décisions des branches et des appareils à tester sur 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 avant envoi dans les répertoires associés. Le mappage de test vous permet d'ajouter le même ensemble de tests pour envoyer les vérifications avant l'envoi, avec une simple modification dans l'arborescence source Android.

Consultez les exemples suivants:

Ajouter des tests de pré-envoi à TEST_MAPPING pour services.core

Ajouter des tests avant envoi à TEST_MAPPING pour les outils/dexter à l'aide d'importations

Le mappage des tests s'appuie sur le Trade Fédération (TF) Test Harness pour l'exécution des tests et les rapports sur les résultats.

Définir des groupes de test

Testez les tests des groupes de mappage via un groupe de test. Le nom d'un groupe de test peut être n'importe quelle chaîne. Par exemple, l'instruction presubmit peut être l'exécution d'un groupe de tests lors de la validation des modifications. Les tests postsubmit peuvent être utilisés pour valider les compilations après la fusion des modifications.

Règles du script de compilation du package

Pour que Trade Federation Test Harness exécute les modules de test du mappage de test pour une version donnée, test_suites doit être défini pour Soong ou LOCAL_COMPATIBILITY_SUITE pour "Make" sur l'une de ces deux suites:

  • general-tests : tests qui ne dépendent pas d'une fonctionnalité spécifique à l'appareil (par exemple, le matériel propre au fournisseur que la plupart des appareils ne possèdent pas). La plupart des tests doivent faire partie de la suite de tests généraux, même s'ils sont spécifiques à une 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 appareil.
  • device-tests : tests qui dépendent des fonctionnalités spécifiques à l'appareil. Ces tests se trouvent généralement sous vendor/. Étant donné que le terme "spécifique à l'appareil" ne fait pas référence à une fonctionnalité d'ABI ni à un SoC que d'autres appareils pourraient avoir ou non, mais uniquement à une fonctionnalité propre à un appareil, cela s'applique aux tests JUnit tout autant que les tests natifs GTest (qui doivent généralement être general-tests, même s'ils sont spécifiques à l'ABI).

Exemples :

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

Configurer des tests à exécuter dans une suite de tests

Pour qu'un test s'exécute dans une suite de tests, il doit:

  • ne doit disposer d'aucun fournisseur de compilation.
  • doivent effectuer un nettoyage après la fin du test, par exemple en supprimant les fichiers temporaires générés lors du test.
  • modifier les paramètres système sur la valeur par défaut ou d'origine.
  • ne doit pas supposer qu'un appareil se trouve dans un certain état, par exemple "root ready". La plupart des tests ne nécessitent pas de droits racine pour s'exécuter. Si un test doit nécessiter un accès racine, il doit le spécifier avec un RootTargetPreparer dans son AndroidTest.xml, comme dans l'exemple suivant:
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>

Créer des fichiers de mappage de test

Pour le répertoire nécessitant une couverture de test, ajoutez simplement un fichier JSON TEST_MAPPING semblable à l'exemple ci-dessous. Ces règles garantissent que les tests s'exécutent lors de vérifications avant envoi lorsque des fichiers sont modifiés dans ce répertoire ou dans l'un de ses sous-répertoires.

Suivre un exemple

Voici un exemple de fichier TEST_MAPPING (au format JSON, mais avec les commentaires acceptés):

{
  "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éfinir les attributs

Dans l'exemple ci-dessus, presubmit et postsubmit sont les noms de chaque groupe de test. Pour en savoir plus sur les groupes de test, consultez Définir des groupes de test.

Le nom du module de test ou du nom du test d'intégration de la fédération de fédération (chemin d'accès à la 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 name ne peut pas utiliser la classe name ni la méthode de test name. Pour affiner les tests à exécuter, vous pouvez utiliser des options telles que include-filter ici. Consultez la section (exemple d'utilisation "include-filter").

Le paramètre host d'un test indique s'il s'agit d'un test sans appareil exécuté sur l'hôte ou non. La valeur par défaut est false, ce qui signifie que le test nécessite l'exécution d'un appareil. Les types de test compatibles 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 d'expression régulière correspondant au chemin relatif de tout fichier de code source (par rapport au répertoire contenant le fichier TEST_MAPPING). Dans l'exemple ci-dessus, le test CtsWindowManagerDeviceTestCases ne s'exécute en pré-envoi que lorsqu'un fichier Java commence par "Window" ou "Activity", qui existe dans le même répertoire du fichier TEST_MAPPING ou de l'un de ses sous-répertoires, est modifié. Les barres obliques inverses \ doivent être échappées comme 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 des répertoires parents du chemin importé seront également inclus. Le mappage de test autorise les importations imbriquées. Cela signifie que deux fichiers TEST_MAPPING peuvent s'importer l'un l'autre et que le mappage de test peut fusionner correctement les tests inclus.

L'attribut options contient des options de ligne de commande TradeFed supplémentaires.

Pour obtenir la liste complète des options disponibles pour un test donné, exécutez la commande suivante:

tradefed.sh run commandAndExit [test_module] --help

Pour en savoir plus sur le fonctionnement des options, consultez la page Traitement des options négociées .

Exécuter des tests avec Atest

Pour exécuter en local les règles de test avant envoi, procédez comme suit:

  1. Accédez au répertoire contenant le fichier TEST_MAPPING.
  2. Exécutez la commande suivante:
atest

Tous les tests de pré-envoi configurés dans les fichiers TEST_MAPPING du répertoire actuel et de ses répertoires parents sont exécutés. Atest localisera et exécutera deux tests de pré-envoi (A et B).

Il s'agit du moyen le plus simple d'exécuter des tests de préenvoi 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 dans tous ses répertoires parents.

Structurer le code source

L'exemple suivant montre comment configurer les fichiers TEST_MAPPING 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écifier les 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écute deux tests (A, B).

atest --test-mapping src/project_1

Exécuter les règles de test post-envoi

Vous pouvez également utiliser cette commande pour exécuter les règles de test postsubmit définies dans TEST_MAPPING dans src_path (CWD par défaut) et ses répertoires parents:

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

Exécuter uniquement les tests qui ne nécessitent aucun appareil

Vous pouvez utiliser l'option --host pour Atest afin d'exécuter uniquement des tests configurés sur l'hôte qui ne nécessitent aucun appareil. Sans cette option, Atest exécute les deux tests : ceux nécessitant un appareil et ceux exécutés sur l'hôte, et ne nécessitent aucun appareil. Les tests seront exécutés dans deux suites distinctes.

atest [--test-mapping] --host

Identifier les groupes de test

Vous pouvez spécifier des groupes de test dans la commande Atest. La commande suivante exécute tous les tests postsubmit liés aux fichiers du répertoire src/project_1, qui ne contient qu'un seul test (C).

Vous pouvez également 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

Inclure les sous-répertoires

Par défaut, l'exécution de tests dans TEST_MAPPING avec Atest n'exécute que les tests de pré-envoi configurés dans le fichier TEST_MAPPING dans CWD (ou dans un répertoire donné) et dans 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écute deux tests (A et B).

Les commentaires au niveau de la ligne sont acceptés

Vous pouvez ajouter un commentaire au format // au niveau de la ligne pour étoffer le fichier TEST_MAPPING avec une description du paramètre ci-dessous. ATest et la fédération commerciale effectueront le prétraitement de TEST_MAPPING dans un format JSON valide sans commentaires. Pour que le fichier JSON reste propre et lisible, seul le commentaire au format // au niveau de la ligne est accepté.

Exemple :

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