Questa è una breve introduzione al mapping dei test e una spiegazione di come iniziare a configurare i test in 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 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 pre-invio nelle directory
associate. Con il mapping dei test, puoi aggiungere lo stesso insieme di test ai controlli pre-invio con una modifica minima all'interno dell'albero di origine Android.
Vedi questi 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 suitegeneral-tests, anche se sono specifici per un ABI, una bitness o funzionalità hardware come HWASan (esiste un targettest_suitesseparato 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 invendor/. 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 comegeneral-testsanche 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:
- 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
RootTargetPreparernel relativoAndroidTest.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 pre-invio quando vengono toccati file nella 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'utilizzo di esempio di
include-filter.
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, il che 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.
Convalide TEST_MAPPING
Quando invii modifiche che modificano i file TEST_MAPPING, vengono eseguiti controlli pre-invio per garantire la correttezza:
- Convalida dei pattern di file: garantisce che tutte le espressioni regolari in
file_patternscorrispondano ad almeno un file nel repository. I pattern obsoleti che non corrispondono a nessun file causano l'errore del controllo. - Convalida in fase di build: promuove gli avvisi di convalida in fase di build raccolti dalla build per bloccare gli errori in pre-invio per i rami principali. Gli avvisi comuni includono:
- Moduli inesistenti: riferimento a un nome di modulo di test che non esiste nel codebase, ad esempio quando il nome contiene un errore di battitura.
- Importazioni non valide: percorsi di riferimento in
importsche non esistono o non contengono un fileTEST_MAPPING. - Problemi di schema: utilizzo di chiavi non supportate o strutture non valide nella configurazione JSON.
Eseguire test con Atest
Per eseguire le regole di test pre-invio in locale:
- Vai alla directory contenente il file
TEST_MAPPING. Esegui il comando:
atest
Vengono eseguiti tutti i test 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 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 post-invio
Puoi anche utilizzare questo comando 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
Eseguire solo i test che non richiedono alcun dispositivo
Puoi utilizzare l'opzione --host per Atest per eseguire solo i test configurati sull'host che non richiedono alcun dispositivo. Senza questa opzione, Atest esegue entrambi i test, quelli che richiedono un dispositivo e quelli in esecuzione 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
Includere le sottodirectory
Per impostazione predefinita, l'esecuzione dei test in TEST_MAPPING con Atest esegue solo i test 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"
}
]
}