Questa categoria di test di misurazione non è molto diversa da quella che ha come target le normali applicazioni Android. È importante notare che l'applicazione di test che includeva la misurazione deve essere firmata con lo stesso certificato dell'applicazione di destinazione.
Tieni presente che questa guida presuppone che tu abbia già una certa conoscenza del flusso di lavoro dell'albero di origine della piattaforma. In caso contrario, consulta la sezione Requisiti. L'esempio trattato qui riguarda la scrittura di un nuovo test di misurazione con il pacchetto di destinazione impostato sul proprio pacchetto dell'applicazione di test. Se non hai familiarità con il concetto, leggi la Introduzione ai test della piattaforma.
Questa guida utilizza il seguente test come esempio:
- frameworks/base/packages/Shell/test
Ti consigliamo di esaminare il codice per avere un'impressione approssimativa prima di procedere.
Scegli una posizione di origine
Poiché il test di misurazione avrà come target un'applicazione, la convenzione è quella di posizionare il codice sorgente del test in una directory tests
nella directory principale della directory sorgente del componente nell'albero del codice sorgente della piattaforma.
Consulta altre discussioni sulla posizione della sorgente nell'esempio end-to-end per i test di automisura.
File manifest
Come per una normale applicazione, ogni modulo di test di misurazione richiede un
file manifest. Se assegni al file il nome AndroidManifest.xml
e lo specifichi accanto
a Android.mk
per il modulo di test, questo verrà incluso automaticamente dal
makefile principale di BUILD_PACKAGE
.
Prima di procedere, ti consigliamo vivamente di consultare la Panoramica del file manifest dell'app.
Questa sezione fornisce una panoramica dei componenti di base di un file manifest e delle relative funzionalità.
Puoi accedere alla versione più recente del file manifest per la modifica di gerrit di esempio all'indirizzo: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml
Per comodità, è incluso uno snapshot:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
<application>
<uses-library android:name="android.test.runner" />
<activity
android:name="com.android.shell.ActionSendMultipleConsumerActivity"
android:label="ActionSendMultipleConsumer"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
</manifest>
Alcune osservazioni specifiche sul file manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
L'attributo package
è il nome del pacchetto dell'applicazione: si tratta dell'identificatore
univoco utilizzato dal framework dell'applicazione Android per identificare un'applicazione (o, in questo contesto, la tua applicazione di test). Ogni utente del sistema può installare una sola applicazione con quel nome del pacchetto.
Poiché si tratta di un pacchetto di applicazioni di test, indipendente dal pacchetto di applicazioni sottoposto a test, è necessario utilizzare un nome di pacchetto diverso: una convenzione comune è l'aggiunta di un suffisso .test
.
Inoltre, questo attributo package
è lo stesso restituito da ComponentName#getPackageName()
e anche quello che utilizzeresti per interagire con vari comandi secondari pm
tramite adb shell
.
Nota anche che, sebbene il nome del pacchetto sia generalmente nello stesso stile del nome di un pacchetto Java, in realtà ha pochissime cose a che fare con questo. In altre parole, il pacchetto dell'applicazione (o del test) può contenere classi con qualsiasi nome del pacchetto, anche se, d'altra parte, puoi optare per la semplicità e avere il nome del pacchetto Java di primo livello nell'applicazione o nel test identico al nome del pacchetto dell'applicazione.
<uses-library android:name="android.test.runner" />
Questo è necessario per tutti i test di strumentazione poiché le classi correlate sono imballate in un file della libreria JAR del framework separato, pertanto richiedono voci aggiuntive del percorso di classe quando il pacchetto di test viene richiamato dal framework dell'applicazione.
android:targetPackage="com.android.shell"
In questo modo, il pacchetto target della misurazione viene impostato su com.android.shell
.
Quando la strumentazione viene invocata tramite il comando am instrument
, il framework riavvia il processo com.android.shell
e inietta il codice di strumentazione nel processo per l'esecuzione del test. Ciò significa anche che il codice di test avrà accesso a tutte le istanze di classe in esecuzione nell'applicazione sottoposta al test e potrebbe essere in grado di manipolare lo stato dipende dagli hook di test esposti.
File di configurazione semplice
Ogni nuovo modulo di test deve avere un file di configurazione per indirizzare il sistema di compilazione con metadati del modulo, dipendenze del tempo di compilazione e istruzioni per la pacchettizzazione. Nella maggior parte dei casi, l'opzione del file Blueprint basato su Soong è sufficiente. Per maggiori dettagli, consulta la sezione Configurazione di test semplici.
File di configurazione complesso
Per test più complessi, devi anche scrivere un file di configurazione del test per Trade Federation, l'ambiente di test di Android.
La configurazione del test può specificare opzioni di configurazione del dispositivo speciali e argomenti predefinite per fornire la classe di test.
Puoi accedere alla versione più recente del file di configurazione per la modifica di gerrit di esempio all'indirizzo: frameworks/base/packages/Shell/tests/AndroidTest.xml
Per comodità, è incluso uno snapshot:
<configuration description="Runs Tests for Shell.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="ShellTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.shell.tests" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
</configuration>
Alcune osservazioni selezionate sul file di configurazione del test:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk"/>
</target_preparer>
Questo indica a Trade Federation di installare ShellTests.apk sul dispositivo di destinazione utilizzando un target_preparer specificato. Gli sviluppatori della Trade Federation hanno a disposizione molti preparatori di destinazione, che possono essere utilizzati per garantire che il dispositivo sia configurato correttamente prima dell'esecuzione del test.
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.shell.tests"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
Questo specifica la classe di test Trade Federation da utilizzare per eseguire il test e passa il pacchetto sul dispositivo da eseguire e il framework di test runner, che in questo caso è JUnit.
Consulta questa pagina per saperne di più sulle configurazioni dei moduli di test
Funzionalità di JUnit4
L'utilizzo della libreria android-support-test
come runner di test consente l'adozione delle nuove
classi di test dello stile JUnit4 e la modifica del file gerrit di esempio contiene un utilizzo
di base delle sue funzionalità.
È possibile accedere al codice sorgente più recente per la modifica del gerrit di esempio all'indirizzo: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
Sebbene i pattern di test siano in genere specifici per i team di componenti, esistono alcuni pattern di utilizzo utili in generale.
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {
Una differenza significativa di JUnit4 è che i test non sono più tenuti a ereditare da una classe di test di base comune. Invece, scrivi i test in classi Java semplici e utilizzi le annotazioni per indicare determinati vincoli e configurazioni di test. In questo esempio, dichiariamo che questa classe deve essere eseguita come test JUnit4 Android.
L'annotazione @SmallTest
ha specificato una dimensione del test per l'intera classe di test: tutti i metodi di test aggiunti a questa classe di test ereditano questa annotazione della dimensione del test.
pre test class setup, post test tear down e post test class tear down:
simili ai metodi setUp
e tearDown
in JUnit4.
L'annotazione Test
viene utilizzata per annotare il test effettivo.
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
L'annotazione @Before
viene utilizzata nei metodi di JUnit4 per eseguire la configurazione precedente al test.
Sebbene non venga utilizzato in questo esempio, è disponibile anche @After
per l'eliminazione post-test.
Analogamente, le annotazioni @BeforeClass
e @AfterClass
possono essere utilizzate sui metodi di JUnit4 per eseguire la configurazione prima di eseguire tutti i test in una classe di test e il teardown successivamente. Tieni presente che i metodi di configurazione e di eliminazione
dell'ambito della classe devono essere statici.
Per quanto riguarda i metodi di test, a differenza delle versioni precedenti di JUnit, non è più necessario iniziare il nome del metodo con test
, ma ogni metodo deve essere annotato con @Test
. Come di consueto, i metodi di test devono essere pubblici, dichiarare nessun valore restituito,
non accettare parametri e possono generare eccezioni.
Context context = InstrumentationRegistry.getTargetContext();
Poiché i test JUnit4 non richiedono più una classe di base comune, non è più necessario ottenere istanze Context
tramite getContext()
o getTargetContext()
tramite i metodi della classe di base. Il nuovo test runner li gestisce tramite InstrumentationRegistry
, dove viene memorizzata la configurazione contestuale e ambientale creata dal framework di misurazione. Tramite questo corso, puoi anche chiamare:
getInstrumentation()
: l'istanza della classeInstrumentation
getArguments()
: gli argomenti della riga di comando passati aam instrument
tramite-e <key> <value>
Esegui la compilazione e i test in locale
Per i casi d'uso più comuni, utilizza Atest.
Per casi più complessi che richiedono una maggiore personalizzazione, segui le istruzioni di strumentazione.