Scegli come target un esempio di app

Questa categoria di test della strumentazione non è molto diversa da quelli destinati alle normali applicazioni Android. Vale la pena notare che l'applicazione di test che include la strumentazione deve essere firmata con lo stesso certificato dell'applicazione a cui è destinata.

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, fare riferimento ai Requisiti . L'esempio qui trattato riguarda la scrittura di un nuovo test di strumentazione con il pacchetto target impostato nel proprio pacchetto dell'applicazione di test. Se non hai familiarità con il concetto, leggi l' introduzione al test della piattaforma .

Questa guida utilizza il seguente test come esempio:

  • framework/base/pacchetti/Shell/test

Si consiglia di sfogliare prima il codice per farsi un'idea approssimativa prima di procedere.

Decidi la posizione della fonte

Poiché il test della strumentazione sarà indirizzato a un'applicazione, la convenzione prevede di posizionare il codice sorgente del test in una directory tests sotto la radice della directory di origine del componente nell'albero dei sorgenti della piattaforma.

Consulta ulteriori discussioni sulla posizione dell'origine nell'esempio end-to-end per i test autostrumentanti .

Fascicolo manifesto

Proprio come una normale applicazione, ogni modulo di test della strumentazione necessita di un file manifest. Se assegni al file il nome AndroidManifest.xml e lo fornisci accanto ad Android.mk per il tuo tmodule di test, verrà incluso automaticamente dal makefile principale BUILD_PACKAGE .

Prima di procedere oltre, si consiglia vivamente di consultare prima la Panoramica del manifest dell'app .

Ciò fornisce una panoramica dei componenti di base di un file manifest e delle loro funzionalità.

È possibile accedere all'ultima versione del file manifest per la modifica gerrit di esempio all'indirizzo: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml

Per comodità è inclusa qui un'istantanea:

<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>

Alcuni commenti selezionati 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: questo è l'identificatore univoco che il framework dell'applicazione Android utilizza per identificare un'applicazione (o in questo contesto: la tua applicazione di test). Ogni utente nel sistema può installare solo un'applicazione con quel nome di pacchetto.

Poiché si tratta di un pacchetto dell'applicazione di test, indipendente dal pacchetto dell'applicazione sotto test, è necessario utilizzare un nome di pacchetto diverso: una convenzione comune è quella di aggiungere un suffisso .test .

Inoltre, questo attributo package è lo stesso restituito da ComponentName#getPackageName() e anche lo stesso che utilizzeresti per interagire con vari comandi secondari pm tramite adb shell .

Tieni inoltre presente che, sebbene il nome del pacchetto abbia tipicamente lo stesso stile del nome di un pacchetto Java, in realtà ha pochissime cose a che fare con esso. In altre parole, il pacchetto della tua applicazione (o test) può contenere classi con qualsiasi nome di pacchetto, anche se, d'altro canto, potresti optare per la semplicità e avere il nome del pacchetto Java di primo livello nella tua applicazione o test identico al nome del pacchetto dell'applicazione.

<uses-library android:name="android.test.runner" />

Ciò è necessario per tutti i test di strumentazione poiché le classi correlate sono incluse in un file di libreria jar del framework separato, pertanto richiede voci del percorso di classe aggiuntive quando il pacchetto di test viene richiamato dal framework dell'applicazione.

android:targetPackage="com.android.shell"

Ciò imposta il pacchetto di destinazione della strumentazione su com.android.shell . Quando la strumentazione viene richiamata tramite il comando am instrument , il framework riavvia il processo com.android.shell e inserisce il codice della strumentazione nel processo per l'esecuzione del test. Ciò significa anche che il codice di test avrà accesso a tutte le istanze della classe in esecuzione nell'applicazione sotto test e potrebbe essere in grado di manipolare lo stato a seconda degli hook di test esposti.

File di configurazione semplice

Ogni nuovo modulo di test deve avere un file di configurazione per dirigere il sistema di compilazione con metadati del modulo, dipendenze in fase di compilazione e istruzioni di confezionamento. Nella maggior parte dei casi, l'opzione file Blueprint basata su Soong è sufficiente. Per i dettagli vedere Configurazione test semplice .

File di configurazione complesso

Per test più complessi, devi anche scrivere un file di configurazione del test per il test cablaggio di Android, Trade Federation .

La configurazione del test può specificare opzioni speciali di configurazione del dispositivo e argomenti predefiniti per fornire la classe di test.

È possibile accedere all'ultima versione del file di configurazione per la modifica gerrit di esempio all'indirizzo: frameworks/base/packages/Shell/tests/AndroidTest.xml

Per comodità è inclusa qui un'istantanea:

<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>

Ciò indica a Trade Federation di installare ShellTests.apk sul dispositivo di destinazione utilizzando un target_preparer specificato. Ci sono molti preparatori di target a disposizione degli sviluppatori nella Trade Federation e questi 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 della Trade Federation da utilizzare per eseguire il test e passa nel pacchetto sul dispositivo da eseguire e il framework del test runner che in questo caso è JUnit.

Cerca qui per ulteriori informazioni sulle configurazioni del modulo di test

Funzionalità di JUnit4

L'utilizzo della libreria android-support-test come test runner consente l'adozione di nuove classi di test in stile JUnit4 e la modifica gerrit di esempio contiene alcuni utilizzi molto basilari delle sue funzionalità.

È possibile accedere al codice sorgente più recente per la modifica gerrit di esempio all'indirizzo: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Sebbene i modelli di test siano generalmente specifici per i team componenti, esistono alcuni modelli di utilizzo generalmente utili.

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

Una differenza significativa in JUnit4 è che non è più necessario che i test ereditino da una classe di test di base comune; invece, scrivi test in semplici classi Java e usi l'annotazione per indicare determinate impostazioni e vincoli di test. In questo esempio, stiamo indicando che questa classe deve essere eseguita come test Android JUnit4.

L'annotazione @SmallTest specifica 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. Impostazione della classe pre-test, smontaggio post-test e smontaggio della classe post-test: simile ai metodi setUp e tearDown in JUnit4. L'annotazione Test viene utilizzata per annotare il test vero e proprio.

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

L'annotazione @Before viene utilizzata sui metodi di JUnit4 per eseguire la configurazione pre-test. Sebbene non sia utilizzato in questo esempio, c'è anche @After per lo smontaggio post-test. Allo stesso modo, 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 lo smontaggio successivamente. Tieni presente che i metodi di installazione e smontaggio dell'ambito della classe devono essere statici.

Per quanto riguarda i metodi di test, a differenza della versione precedente di JUnit, non è più necessario che il nome del metodo inizi con test , ma ciascuno di essi deve essere annotato con @Test . Come al solito, i metodi di test devono essere pubblici, non dichiarare alcun valore restituito, non accettare parametri e possono generare eccezioni.

        Context context = InstrumentationRegistry.getTargetContext();

Poiché i test JUnit4 non richiedono più una classe base comune, non è più necessario ottenere istanze Context tramite getContext() o getTargetContext() tramite i metodi della classe base; invece, il nuovo test runner li gestisce tramite InstrumentationRegistry dove viene archiviata la configurazione contestuale e ambientale creata dal framework di strumentazione. Attraverso questo corso puoi anche chiamare:

  • getInstrumentation() : l'istanza della classe Instrumentation
  • getArguments() : gli argomenti della riga di comando passati am instrument tramite -e <key> <value>

Costruisci e testa localmente

Per i casi d'uso più comuni, utilizzare Atest .

Per casi più complessi che richiedono personalizzazioni più impegnative, seguire le istruzioni della strumentazione .