Exemple de ciblage d'une application

Cette catégorie de tests d'instrumentation n'est pas très différente des critères de ciblage les applications Android standards. Notez que l'application de test incluant l'instrumentation doit être signée avec le même certificat que l'application qu'il cible.

Dans ce guide, nous partons du principe que vous avez déjà quelques connaissances en de l'arborescence source de la plate-forme. Si ce n'est pas le cas, consultez les Conditions requises. L'exemple présenté ici consiste à écrire un nouveau test d'instrumentation avec dans son propre package d'application de test. Si vous ne connaissez pas les consultez l'introduction aux tests de plates-formes.

Ce guide utilise le test suivant comme exemple:

  • frameworks/base/packages/interface système/tests

Nous vous recommandons de parcourir d'abord le code pour avoir une idée générale avant de continuer.

Choisir un emplacement source

Étant donné que le test d'instrumentation ciblera une application, la convention consiste à placer le code source de test dans un répertoire tests, à la racine de votre le répertoire source du composant dans l'arborescence source de la plate-forme.

Consultez d'autres discussions sur l'emplacement source dans l'exemple de bout en bout pour d'auto-instrumentation.

Fichier manifeste

Tout comme les applications standards, chaque module de test d'instrumentation nécessite fichier manifeste. Si vous nommez le fichier AndroidManifest.xml et que vous le fournissez à Android.mk pour votre module de test, il sera inclus automatiquement par Makefile de base BUILD_PACKAGE.

Avant de continuer, nous vous recommandons vivement de consulter les Présentation du fichier manifeste d'application en premier.

Vous trouverez ici une présentation des composants de base d'un fichier manifeste et de leurs fonctionnalités.

La dernière version du fichier manifeste pour l'exemple de modification Gerrit est accessible à l'adresse: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml

Un instantané est inclus ici pour plus de commodité:

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

Quelques remarques concernant le fichier manifeste:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

L'attribut package correspond au nom du package de l'application: il s'agit de l'attribut que le framework d'application Android utilise pour identifier application (ou, dans ce contexte, votre application de test). Chaque utilisateur du système ne peut installer qu'une seule application avec ce nom de package.

Comme il s'agit d'un package d'application de test, indépendant du package d'application testé, un nom de package différent doit être utilisé : une convention courante consiste à ajouter un suffixe .test.

De plus, cet attribut package est identique à ce que ComponentName#getPackageName() renvoie, et à celui que vous utiliseriez pour interagir avec diverses sous-commandes pm via adb shell.

Notez également que, même si le nom du package est généralement de la même manière, en tant que nom de package Java, il a en fait très peu de choses à faire avec. Dans d'autres votre package d'application (ou de test) peut contenir des classes avec n'importe quel package de noms de domaine. D'un autre côté, vous pouvez opter pour la simplicité et faire en sorte du package Java du niveau de service dans votre application ou test identique à l'application nom du package.

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

Cela est obligatoire pour tous les tests d'instrumentation, car les classes associées sont empaquetés dans un fichier de bibliothèque JAR de framework distinct, ce qui nécessite Entrées classpath lorsque le package de test est appelé par le framework d'application.

android:targetPackage="com.android.shell"

Cela définit le package cible de l'instrumentation sur com.android.shell. Lorsque l'instrumentation est appelée via la commande am instrument, le framework redémarre le processus com.android.shell et injecte le code d'instrumentation dans le processus d'exécution du test. Cela signifie également que le code de test l'accès à toutes les instances de classe s'exécutant dans l'application testée et peut de pouvoir manipuler l'état dépend des hooks de test exposés.

Fichier de configuration simple

Chaque nouveau module de test doit disposer d'un fichier de configuration le système de compilation avec les métadonnées du module, les dépendances au moment de la compilation et le packaging instructions. Dans la plupart des cas, l’option de fichier de plan basée sur Soong est suffisant. Pour en savoir plus, consultez la page Configuration de test simple.

Fichier de configuration complexe

Pour les tests plus complexes, vous devez également écrire une configuration de test pour l'outil de test d'Android, Trade Fédération.

La configuration de test peut spécifier des options de configuration d'appareil spéciales et des paramètres par défaut pour fournir la classe de test.

Vous pouvez accéder à la dernière version du fichier de configuration de l'exemple de modification Gerrit à l'adresse : frameworks/base/packages/Shell/tests/AndroidTest.xml.

Un instantané est inclus ici pour plus de commodité:

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

Quelques remarques sur le fichier de configuration de test :

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="ShellTests.apk"/>
</target_preparer>

Cela indique à Trade Federation d'installer le fichier ShellTests.apk sur l'appareil cible à l'aide d'un target_preparer spécifié. De nombreux préparateurs de cibles sont disponibles pour les développeurs dans Trade Federation. Ils peuvent être utilisés pour s'assurer que l'appareil est correctement configuré avant l'exécution des tests.

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

Cela spécifie la classe de test de la fédération de commerce à utiliser pour exécuter le test et transmet le package sur l'appareil à exécuter et le lanceur de test qui est JUnit dans ce cas.

Pour en savoir plus sur les configurations de module de test, consultez cette page.

Fonctionnalités de JUnit4

L'utilisation de la bibliothèque android-support-test en tant qu'exécuteur de test permet d'adopter de nouvelles à des classes de test de style JUnit4, et l'exemple de modification de gerrit contient des éléments de ses fonctionnalités.

Le code source le plus récent pour l'exemple de modification Gerrit est disponible à l'adresse suivante: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Bien que les modèles de test soient généralement spécifiques aux équipes de composants, il existe des modèles d'utilisation généralement utiles.

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

Une différence importante dans JUnit4 est que les tests ne sont plus tenus d'hériter d'une classe de test de base commune. Au lieu de cela, vous écrivez des tests dans des classes Java simples et utilisez des annotations pour indiquer certaines configurations et contraintes de test. Dans Dans cet exemple, nous indiquons que cette classe doit être exécutée en tant que Test JUnit4.

L'annotation @SmallTest a spécifié une taille de test pour l'ensemble de la classe de test: tous Les méthodes de test ajoutées à cette classe de test héritent de cette annotation de taille de test. Suppression avant la configuration du cours, suppression post-test et suppression après test: semblables aux méthodes setUp et tearDown dans JUnit4. L'annotation Test permet d'annoter le test réel.

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

L'annotation @Before est utilisée par JUnit4 sur les méthodes pour effectuer la configuration avant le test. Bien que n'étant pas utilisé dans cet exemple, @After est également utilisé pour le démontage après le test. De même, les annotations @BeforeClass et @AfterClass peuvent être utilisées sur par JUnit4 pour effectuer la configuration avant d'exécuter tous les tests dans une classe de test, puis de le supprimer. Notez que les méthodes de configuration et de suppression à l'échelle de la classe doit être statique.

En ce qui concerne les méthodes de test, contrairement à la version précédente de JUnit, elles n'ont plus besoin Pour commencer le nom de la méthode par test, chacune d'entre elles doit être annotée avec @Test. Comme d'habitude, les méthodes de test doivent être publiques, ne déclarer aucune valeur renvoyée, n'acceptent aucun paramètre et peuvent générer des exceptions.

        Context context = InstrumentationRegistry.getTargetContext();

Comme les tests JUnit4 ne nécessitent plus de classe de base commune, il n'est plus nécessaire nécessaire pour obtenir des instances Context via getContext() ou getTargetContext() via les méthodes de la classe de base ; à la place, le nouveau lanceur de test les gère via InstrumentationRegistry. où la configuration contextuelle et environnementale créée par le framework d'instrumentation stockées. Vous pouvez également appeler les méthodes suivantes :

  • getInstrumentation(): instance de la classe Instrumentation.
  • getArguments(): arguments de ligne de commande transmis à am instrument via -e <key> <value>

Compiler et tester en local

Pour les cas d'utilisation les plus courants, utilisez Confirmer :

Pour les cas plus complexes nécessitant une personnalisation plus poussée, suivez le instructions d'instrumentation.