Mappatura test

Questa è una breve introduzione al mapping dei test e una spiegazione di come iniziare a configurare i test nell'Android Open Source Project (AOSP).

Informazioni sul mapping dei test

Il mapping dei test è un approccio basato su Gerrit che consente agli sviluppatori di creare regole di test di pre-invio e post-invio direttamente nell'albero di origine Android e di lasciare all'infrastruttura di test le decisioni relative a rami e 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 il mapping dei test, puoi aggiungere lo stesso insieme di test ai controlli di pre-invio con una modifica minima all'interno dell'albero di origine Android.

Ecco alcuni esempi:

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

Definire i gruppi di test

Il mapping dei test raggruppa i test 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. E postsubmit può essere il nome dei test utilizzati per convalidare le build dopo l'unione delle modifiche.

Regole dello script di build del pacchetto

Affinché il framework di test Trade Federation 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 in una di queste due suite:

  • general-tests è per i test che non dipendono da funzionalità specifiche del dispositivo (ad esempio hardware specifico del fornitore che la maggior parte dei dispositivi non ha). La maggior parte dei test deve essere nella suite general-tests, anche se sono specifici per un ABI o una bitness 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 da funzionalità specifiche del dispositivo. In genere questi test si trovano in vendor/. Specifico del dispositivo si riferisce solo alle funzionalità univoche di un dispositivo, quindi si applica sia ai test JUnit sia ai test GTest (che in genere devono essere contrassegnati come general-tests anche se sono specifici per 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:

  • Non deve avere alcun provider di build.
  • Deve eseguire la pulizia al termine, ad esempio eliminando eventuali file temporanei generati durante il test.
  • Deve modificare le impostazioni di sistema sul valore predefinito o originale.
  • Non deve presupporre che un dispositivo sia in un determinato stato, ad esempio root pronto. La maggior parte dei test non richiede privilegi di root per l'esecuzione. Se un test deve richiedere la root, deve specificarlo con RootTargetPreparer nel relativo AndroidTest.xml, come nell'esempio seguente:

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

Creare file di mapping dei test

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

Seguire un esempio

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

{
  "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 ogni gruppo di test. Per ulteriori informazioni sui gruppi di test, consulta la sezione Definire 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. Consulta l'esempio di utilizzo include-filter campione.

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 di un dispositivo. I tipi di test supportati sono HostGTest per i file 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 viene eseguito in pre-invio solo quando un file Java inizia con o, che esiste nella stessa directory del file o in una delle relative sottodirectory.CtsWindowManagerDeviceTestCasesWindowActivityTEST_MAPPING Le barre rovesciate (\) devono essere sottoposte a escape perché si trovano in un file JSON.

L'attributo imports consente di includere i test in altri file TEST_MAPPING senza copiare i contenuti. Vengono inclusi anche i file TEST_MAPPING nelle directory principali del percorso importato. Il mapping dei test consente le importazioni nidificate. Ciò significa che due file TEST_MAPPING possono importarsi a vicenda e il mapping dei test può unire i test inclusi.

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

Per visualizzare 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 i 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 corrente e delle relative directory principali. Atest individua ed esegue due test per il pre-invio (A e B).

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

Strutturare il codice sorgente

Questo esempio mostra come configurare i file TEST_MAPPING nell'albero di origine:

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

Specificare 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

Eseguire le regole di test di post-invio

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

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

Eseguire solo i test che non richiedono un dispositivo

Puoi utilizzare l'opzione --host per Atest per eseguire solo i test configurati sull'host che non richiedono un dispositivo. Senza questa opzione, Atest esegue entrambi i test, quelli che richiedono un dispositivo e quelli in esecuzione su un host che non richiede un 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

Includere le sottodirectory

Per impostazione predefinita, l'esecuzione dei test in TEST_MAPPING con Atest esegue solo i test di pre-invio configurati nel file TEST_MAPPING in CWD (o nella directory specificata) e nelle relative directory principali. Se vuoi eseguire i 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 in formato // a livello di riga per completare il file TEST_MAPPING con una descrizione dell'impostazione che segue. ATest e Trade Federation pre-elaborano TEST_MAPPING in un formato JSON valido senza commenti. Per mantenere pulito il file JSON, è supportato solo il commento in formato // a livello di riga.

Esempio:

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