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 suitegeneral-tests
, anche se sono specifici per un'ABI, una profondità di bit o funzionalità hardware come HWASan (esiste un targettest_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 invendor/
. 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 comegeneral-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
nelAndroidTest.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:
- Vai alla directory contenente il file
TEST_MAPPING
. 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"
}
]
}