Ausrichtung auf ein App-Beispiel

Diese Kategorie von Instrumentierungstests unterscheidet sich nicht sehr stark von der Ausrichtung auf Zielgruppen, wie die normalen Android-Apps. Die Testanwendung, die die Instrumentierung enthält, muss mit demselben Zertifikat signiert sein wie die Anwendung, auf die sie ausgerichtet ist.

In diesem Leitfaden wird davon ausgegangen, dass Sie bereits mit dem Workflow für den Plattform-Quellbaum vertraut sind. Ist dies nicht der Fall, lesen Sie die Anforderungen. Das hier behandelte Beispiel ist das Schreiben eines neuen Instrumentierungstests mit -Paket in einem eigenen Testanwendungspaket festgelegt. Wenn Sie nicht mit den finden Sie in der Einführung zu Plattformtests.

In diesem Leitfaden wird der „Folgen“-Test als Beispiel verwendet:

  • Frameworks/Basis/Pakete/Shell/Tests

Es wird empfohlen, sich zuerst den Code anzusehen, um einen groben Eindruck zu erhalten. bevor Sie fortfahren.

Quellspeicherort festlegen

Da der Instrumentierungstest auf eine Anwendung ausgerichtet ist, wird der Test-Quellcode gemäß der Konvention im Stammverzeichnis des Komponentenquellenverzeichnisses im Plattform-Quellbaum in einem tests-Verzeichnis abgelegt.

Weitere Diskussionen über den Speicherort der Quelle finden Sie im End-to-End-Beispiel für selbstinstrumentierende Tests durchführen.

Manifestdatei

Wie bei einer normalen Anwendung benötigt jedes Instrumentierungstestmodul Manifestdatei. Wenn Sie die Datei AndroidManifest.xml nennen und als Nächstes angeben, an Android.mk für Ihr Testmodul, wird es automatisch vom BUILD_PACKAGE-Kern-Makefile.

Bevor Sie fortfahren, sollten Sie sich die Übersicht zum App-Manifest ansehen.

Sie erhalten einen Überblick über die grundlegenden Komponenten einer Manifest-Datei und ihre Funktionalitäten.

Sie können auf die neueste Version der Manifestdatei für die Beispiel-gerrit-Änderung zugreifen um: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml

Der Einfachheit halber finden Sie hier eine Übersicht:

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

Einige ausgewählte Anmerkungen zur Manifestdatei:

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

Das Attribut package ist der Name des Anwendungspakets. Dies ist die eindeutige Kennung, die das Android Application Framework verwendet, um ein oder in diesem Kontext Ihre Testanwendung. Jeder Nutzer im System kann nur eine Anwendung mit diesem Paketnamen installieren.

Da es sich um ein Testanwendungspaket handelt, unabhängig von der Anwendung Zu testendes Paket muss ein anderer Paketname verwendet werden: eine gängige Konvention ist das Hinzufügen des Suffixes .test.

Darüber hinaus entspricht dieses package-Attribut dem, was ComponentName#getPackageName() Ergebnisse, die auch bei der Interaktion mit pm-Unterkonten Befehle über adb shell.

Auch wenn der Paketname in der Regel das gleiche Format hat, als Java-Paketname hat, hat es nur sehr wenig damit zu tun. In anderen Wörter, Ihr Anwendungs- oder Testpaket kann Klassen mit beliebigen Paketen enthalten Sie könnten sich aber für Einfachheit entscheiden und Ihre wichtigsten Java-Paketname in Ihrer Anwendung oder Test, der mit dem der Anwendung identisch ist Paketname.

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

Dies ist für alle Instrumentierungstests erforderlich, da die verwandten Klassen in einer separaten Framework-JAR-Bibliotheksdatei verpackt und erfordert daher zusätzliche classpath-Einträge, wenn das Testpaket vom Anwendungs-Framework aufgerufen wird.

android:targetPackage="com.android.shell"

Dadurch wird das Zielpaket der Instrumentierung auf com.android.shell festgelegt. Wenn die Instrumentierung mit dem Befehl am instrument aufgerufen wird, startet den com.android.shell-Prozess neu und fügt Instrumentierungscode den Prozess der Testausführung. Das bedeutet auch, dass der Testcode Zugriff auf alle Klasseninstanzen, die in der zu testenden Anwendung ausgeführt werden. den Status ändern kann, hängt von den bereitgestellten Test-Hooks ab.

Einfache Konfigurationsdatei

Jedes neue Testmodul muss eine Konfigurationsdatei haben, das Build-System mit Modulmetadaten, Abhängigkeiten zur Kompilierungszeit und Paketerstellung Anleitung. In den meisten Fällen ist die Option für die Blueprint-Datei auf Songbasis ausreichend. Weitere Informationen finden Sie unter Einfache Testkonfiguration.

Komplexe Konfigurationsdatei

Bei komplexeren Tests müssen Sie auch eine Testkonfiguration schreiben -Datei für das Android-Test-Harnisch Trade Federation.

In der Testkonfiguration können spezielle Optionen für die Geräteeinrichtung und Standardargumente für die Testklasse angegeben werden.

Sie können auf die neueste Version der Konfigurationsdatei für die Beispiel-gerrit-Änderung zugreifen um: frameworks/base/packages/Shell/tests/AndroidTest.xml

Hier ist ein Snapshot für Sie:

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

Einige Anmerkungen zur Testkonfigurationsdatei:

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

Damit wird die Handelsföderation angewiesen, die Datei ShellTests.apk auf dem Ziel- mit einem angegebenen target_preparer. In Trade Federation stehen Entwicklern viele Zielvorbereitungstools zur Verfügung, mit denen sie dafür sorgen können, dass das Gerät vor der Testausführung richtig eingerichtet ist.

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

Hier wird die Trade Federation-Testklasse für die Ausführung des Tests angegeben. Außerdem werden das Paket auf dem Gerät, das ausgeführt werden soll, und das Test-Runner-Framework übergeben, in diesem Fall JUnit.

Hier finden Sie weitere Informationen zu Testmodulkonfigurationen

Funktionen von JUnit4

Die Verwendung der android-support-test-Bibliothek als Test-Runner ermöglicht die Einführung neuer JUnit4-Stil-Testklassen. Das Gerrit-Änderungsbeispiel enthält einige sehr einfache die Nutzung seiner Funktionen.

Den neuesten Quellcode für die Beispiel-gerrit-Änderung finden Sie unter: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Während Testmuster in der Regel spezifisch für Komponententeams sind, gibt es einige allgemein nützlichen Nutzungsmustern.

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

Ein wesentlicher Unterschied in JUnit4 besteht darin, dass Tests nicht mehr von einer gemeinsamen Basistestklasse übernehmen; schreiben Sie Tests in einfachem Java und verwenden Annotationen, um bestimmte Testeinrichtung und -einschränkungen anzugeben. In in diesem Beispiel an, dass diese Klasse als Android- JUnit4-Test.

Die Annotation @SmallTest hat eine Testgröße für die gesamte Testklasse angegeben: alle Für Testmethoden, die dieser Testklasse hinzugefügt werden, wird diese Annotation für die Testgröße übernommen. Einrichten der Klasse vor dem Test, Trennen nach dem Test und Trennen nach dem Test: ähnlich wie die Methoden setUp und tearDown in JUnit4. Mit der Anmerkung Test wird der eigentliche Test mit Anmerkungen versehen.

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

Die Annotation @Before wird für Methoden von JUnit4 verwendet, um die Einrichtung vor dem Test durchzuführen. Sie wird in diesem Beispiel zwar nicht verwendet, aber es gibt auch @After für das Teardown nach dem Test. Ebenso können die Annotationen @BeforeClass und @AfterClass für folgende Elemente verwendet werden: Methoden von JUnit4, um die Einrichtung durchzuführen, bevor alle Tests in einer Testklasse ausgeführt werden. und danach reißen. Die Einrichtungs- und Teardown-Methoden für den Klassenbereich muss statisch sein.

Im Gegensatz zu früheren Versionen von JUnit benötigen die Testmethoden keine um den Methodennamen mit test zu beginnen. Stattdessen muss jeder einzelne Name annotiert werden. mit @Test. Wie gewohnt müssen Testmethoden öffentlich sein, keinen Rückgabewert deklarieren keine Parameter und können Ausnahmen auslösen.

        Context context = InstrumentationRegistry.getTargetContext();

Da für die JUnit4-Tests keine gemeinsame Basisklasse erforderlich ist, erforderlich, um Context-Instanzen über getContext() oder getTargetContext() über Basisklassenmethoden; stattdessen der neue Test-Runner verwaltet sie über InstrumentationRegistry in dem das kontext- und umgebungsbezogene Szenario gespeichert sind. In diesem Kurs kannst du außerdem Folgendes erreichen:

  • getInstrumentation(): die Instanz der Klasse Instrumentation
  • getArguments(): die Befehlszeilenargumente, die überam instrument -e <key> <value>

Builds und Tests lokal durchführen

Für die häufigsten Anwendungsfälle Atest:

Bei komplexeren Fällen, die eine stärkere Anpassung erfordern, folgen Sie den Anleitung zur Instrumentierung.