Mappatura test

Questa è una breve introduzione alla mappatura dei test e una spiegazione di come iniziare a configurare i test in Android Open Source Project (AOSP).

Informazioni sulla mappatura dei test

Il test mapping è un approccio basato su Gerrit che consente agli sviluppatori di creare regole di test presubmit e postsubmit direttamente nell'albero dei sorgenti di Android e lasciare all'infrastruttura di test le decisioni relative ai rami e ai dispositivi da testare. Le definizioni di mapping dei test sono file JSON denominati TEST_MAPPING che puoi inserire in qualsiasi directory di origine.

Atest può utilizzare i file TEST_MAPPING per eseguire test di pre-invio nelle directory associate. Con la mappatura dei test, puoi aggiungere lo stesso insieme di test ai controlli pre-invio con una modifica minima all'interno della struttura ad albero delle origini Android.

Vedi questi esempi:

Il mapping dei test si basa sul Trade Federation (TF) test harness per l'esecuzione dei test e la generazione di report sui risultati.

Definisci i gruppi di test

Testa i test dei gruppi di mappatura con un gruppo di test. Il nome di un gruppo di test può essere qualsiasi stringa. Ad esempio, presubmit può essere il nome di un gruppo di test da eseguire durante la convalida delle modifiche. postsubmit possono essere i test utilizzati per convalidare le build dopo l'unione delle modifiche.

Regole per gli script di build dei pacchetti

Affinché l'Trade Federation test harness esegua i moduli di test per una determinata build, questi moduli devono avere un test_suites impostato per Soong o un LOCAL_COMPATIBILITY_SUITE impostato per Make su una di queste due suite:

  • general-tests è per i test che non dipendono da funzionalità specifiche del dispositivo (come hardware specifico del fornitore che la maggior parte dei dispositivi non ha). La maggior parte dei test deve trovarsi nella suite general-tests, anche se sono specifici per un'ABI, una profondità di bit o funzionalità hardware come HWASan (esiste un target test_suites separato per ogni ABI) e anche se devono essere eseguiti su un dispositivo.
  • device-tests è per i test che dipendono dalle funzionalità specifiche del dispositivo. In genere, questi test si trovano in vendor/. Specifico del dispositivo si riferisce solo alle funzionalità uniche di un dispositivo, quindi si applica ai test JUnit e GTest (che in genere devono essere contrassegnati come general-tests anche se sono specifici per l'ABI).

Esempi:

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

Configurare i test da eseguire in una suite di test

Affinché un test venga eseguito all'interno di una suite di test, deve:

  • Non deve avere alcun fornitore di build.
  • Deve eseguire la pulizia al termine, ad esempio eliminando eventuali file temporanei generati durante il test.
  • Devi modificare le impostazioni di sistema impostando il valore predefinito o originale.
  • Non devi presupporre che un dispositivo si trovi in un determinato stato, ad esempio pronto per il root. La maggior parte dei test non richiede il privilegio di root per essere eseguiti. Se un test deve richiedere l'accesso root, deve specificarlo con RootTargetPreparer nel AndroidTest.xml, come nel seguente esempio:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

Crea file di mappatura di test

Per la directory che richiede la copertura del test, aggiungi un file JSON TEST_MAPPING simile all'esempio. Queste regole assicurano che i test vengano eseguiti nei controlli pre-invio quando vengono modificati file in quella directory o in una delle relative sottodirectory.

Segui un esempio

Ecco un file TEST_MAPPING di esempio (in formato JSON, ma con il supporto dei commenti):

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

Imposta gli attributi

Nell'esempio, presubmit e postsubmit sono i nomi di ciascun gruppo di test. Per ulteriori informazioni sui gruppi di test, consulta la sezione Definisci i gruppi di test.

Puoi impostare il nome del modulo di test o il nome del test di integrazione di Trade Federation (percorso della risorsa al file XML di test, ad esempio, uiautomator/uiautomator-demo) nel valore dell'attributo name. Tieni presente che il campo name non può utilizzare la classe name o il metodo di test name. Per restringere i test da eseguire, utilizza opzioni come include-filter. Vedi include-filter esempi di utilizzo.

L'impostazione host di un test indica se il test è un test senza dispositivo in esecuzione sull'host o meno. Il valore predefinito è false, il che significa che il test richiede l'esecuzione su un dispositivo. I tipi di test supportati sono HostGTest per i binari GTest e HostTest per i test JUnit.

L'attributo file_patterns consente di impostare un elenco di stringhe di espressioni regolari per la corrispondenza del percorso relativo di qualsiasi file di codice sorgente (relativo alla directory contenente il file TEST_MAPPING). Nell'esempio, il test CtsWindowManagerDeviceTestCases viene eseguito in presubmit solo quando un file Java inizia con Window o Activity, che si trova nella stessa directory del file TEST_MAPPING o in una delle sue sottodirectory. Le barre rovesciate (\) devono essere sottoposte a escape perché si trovano in un file JSON.

L'attributo imports ti consente di includere test in altri file TEST_MAPPING senza copiare i contenuti. Sono inclusi anche i file TEST_MAPPING nelle directory principali del percorso importato. La mappatura dei test consente importazioni nidificate, il che significa che due file TEST_MAPPING possono importarsi a vicenda e la mappatura dei test può unire i test inclusi.

L'attributo options contiene opzioni aggiuntive della riga di comando di Tradefed.

Per ottenere un elenco completo delle opzioni disponibili per un determinato test, esegui:

tradefed.sh run commandAndExit [test_module] --help

Per ulteriori dettagli sul funzionamento delle opzioni, consulta la sezione Gestione delle opzioni in Tradefed.

Eseguire test con Atest

Per eseguire localmente le regole di test di pre-invio:

  1. Vai alla directory contenente il file TEST_MAPPING.
  2. Esegui il comando:

    atest
    

Vengono eseguiti tutti i test di pre-invio configurati nei file TEST_MAPPING della directory attuale e delle relative directory principali. Atest individua ed esegue due test per il preinvio (A e B).

Questo è il modo più semplice per eseguire test pre-invio nei file TEST_MAPPING nella directory di lavoro attuale (CWD) e nelle directory principali. Atest individua e utilizza il file TEST_MAPPING nella directory di lavoro corrente e in tutte le relative directory principali.

Codice sorgente della struttura

Questo esempio mostra come configurare i file TEST_MAPPING nell'albero delle origini:

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

Contenuti di src/TEST_MAPPING:

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

Contenuti di src/project_1/TEST_MAPPING:

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

Contenuti di src/project_2/TEST_MAPPING:

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

Specifica le directory di destinazione

Puoi specificare una directory di destinazione per eseguire i test nei file TEST_MAPPING in quella directory. Il seguente comando esegue due test (A, B):

atest --test-mapping src/project_1

Esegui regole di test post-invio

Puoi utilizzare questo comando anche per eseguire le regole di test post-invio definite in TEST_MAPPING in src_path (impostazione predefinita su CWD) e nelle relative directory principali:

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

Esegui solo i test che non richiedono un dispositivo

Puoi utilizzare l'opzione --host per Atest per eseguire solo i test configurati rispetto all'host che non richiede alcun dispositivo. Senza questa opzione, Atest esegue entrambi i test, quelli che richiedono un dispositivo e quelli eseguiti su un host che non richiede alcun dispositivo. I test vengono eseguiti in due suite separate:

atest [--test-mapping] --host

Identificare i gruppi di test

Puoi specificare i gruppi di test nel comando Atest. Il seguente comando esegue tutti i test postsubmit relativi ai file nella directory src/project_1, che contiene un solo test (C).

In alternativa, puoi utilizzare :all per eseguire tutti i test indipendentemente dal gruppo. Il seguente comando esegue quattro test (A, B, C, X):

atest --test-mapping src/project_1:all

Includi sottodirectory

Per impostazione predefinita, l'esecuzione di test in TEST_MAPPING con Atest esegue solo i test di pre-invio configurati nel file TEST_MAPPING nella CWD (o nella directory specificata) e nelle relative directory principali. Se vuoi eseguire test in tutti i file TEST_MAPPING nelle sottodirectory, utilizza l'opzione --include-subdir per forzare Atest a includere anche questi test.

atest --include-subdir

Senza l'opzione --include-subdir, Atest esegue solo il test A. Con l'opzione --include-subdir, Atest esegue due test (A, B).

Commento a livello di riga supportato

Puoi aggiungere un commento di formato // a livello di riga per completare il file TEST_MAPPING con una descrizione dell'impostazione che segue. ATest e Trade Federation preelaborano TEST_MAPPING in un formato JSON valido senza commenti. Per mantenere il file JSON pulito, è supportato solo il commento di formato // a livello di riga.

Esempio:

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