Beispiel für selbstinstrumentierende Tests

Wenn ein Instrumentierungstest gestartet wird, ist das Zielpaket mit eingefügtem Instrumentierungscode und der Ausführung initiiert wurde. Eins Ausnahme ist, dass das Zielpaket hier nicht die Android-App sein kann, Framework selbst, wie zum Beispiel das Paket android, da dies zum in der das Android-Framework neu gestartet werden muss, unterstützt die Systemfunktionen, einschließlich der Instrumentierung selbst.

Das bedeutet, dass ein Instrumentierungstest sich nicht selbst in Android einschleusen kann. Framework, auch bekannt als Systemserver, zur Ausführung. Um die Android-Version kann der Testcode nur öffentliche oder preisgegebene API-Oberflächen aufrufen. mit der Android Interface Definition Language AIDL die in der Quellstruktur der Plattform verfügbar sind. Für diese Testkategorie ist es nicht sinnvoll, eine Ausrichtung auf ein bestimmtes Paket vorzunehmen. Daher ist es üblich, Instrumentierungen, die für ein eigenes Testanwendungspaket deklariert werden sollen, wie definiert in einem eigenen <manifest>-Tag von AndroidManifest.xml.

Je nach Anforderungen können Test-Anwendungspakete in dieser Kategorie auch:

  • Bündeln Sie Aktivitäten, die für Tests erforderlich sind.
  • Geben Sie die Nutzer-ID an das System weiter.
  • Sie müssen mit dem Plattformschlüssel signiert sein.
  • Sie werden anhand der Framework-Quelle und nicht des öffentlichen SDKs kompiliert.

Diese Kategorie von Instrumentierungstests wird selbst instrumentieren. Hier sind einige Beispiele für Tests zur der Plattformquelle:

Das hier behandelte Beispiel ist das Schreiben eines neuen Instrumentierungstests mit -Paket in einem eigenen Testanwendungspaket festgelegt. In dieser Anleitung wird Folgendes verwendet: Test als Beispiel:

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

Quellspeicherort festlegen

In der Regel hat Ihr Team bereits ein festes Muster von Orten, die überprüft werden sollen. im Code und an Stellen, an denen Tests hinzugefügt werden können. Die meisten Teams besitzen ein einzelnes Git-Repository oder können Sie eines für andere Teams freigeben, haben aber ein eigenes Unterverzeichnis, Quellcode der Komponente.

Wenn sich der Stammspeicherort der Komponentenquelle unter <component source root> befindet, sind unter den meisten Komponenten die Ordner src und tests vorhanden. Einige zusätzliche Dateien wie Android.mk (oder aufgeteilt in zusätzliche .mk Dateien), die Manifestdatei AndroidManifest.xml und die Testkonfigurationsdatei „AndroidTest.xml“.

Da Sie einen neuen Test hinzufügen, müssen Sie wahrscheinlich tests neben der Komponente src und füllen Sie sie mit Inhalt.

In einigen Fällen hat Ihr Team möglicherweise weitere Verzeichnisstrukturen unter tests da verschiedene Testsuiten in individuelle APKs gepackt werden müssen. Und In diesem Fall müssen Sie ein neues Unterverzeichnis unter tests erstellen.

Unabhängig von der Struktur füllen Sie das Verzeichnis tests oder das neu erstellte Unterverzeichnis mit Dateien, die denen in instrumentation in der Beispiel-gerrit-Änderung. Die jeweiligen Details werden weiter unten in diesem Dokument erläutert.

Manifestdatei

Wie bei einem App-Projekt erfordert jedes Instrumentierungstestmodul einen Manifestdatei mit dem Namen AndroidManifest.xml. Wenn Sie diese Datei automatisch über das BUILD_PACKAGE-Kern-Makefile einbeziehen möchten, legen Sie sie neben der Android.mk-Datei für Ihr Testmodul ab.

Wenn Sie mit der Datei AndroidManifest.xml nicht vertraut sind, sehen Sie in der App-Manifest-Übersicht

Hier sehen Sie eine AndroidManifest.xml-Beispieldatei:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:sharedUserId="android.uid.system"
  package="android.test.example.helloworld" >

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

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Einige ausgewählte Anmerkungen zur Manifestdatei:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

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.

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

Der Paketname hat zwar normalerweise denselben Stil wie ein Java-Paketname, hat aber nur 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.

android:sharedUserId="android.uid.system"

Damit wird deklariert, dass dieser APK-Datei bei der Installation die Berechtigung dieselbe Nutzer-ID, d.h. Laufzeitidentität wie bei der Kernplattform. Beachten Sie, dass dies davon abhängt, dass die APK mit demselben Zertifikat wie die Kernplattform signiert ist (siehe LOCAL_CERTIFICATE in einem vorherigen Abschnitt). Es handelt sich jedoch um unterschiedliche Konzepte:

  • Einige Berechtigungen oder APIs sind signaturgeschützt. Dies erfordert Signaturzertifikat
  • Für einige Berechtigungen oder APIs ist die system-Nutzeridentität des Aufrufers erforderlich. Das aufrufende Paket muss die Nutzer-ID mit system teilen, wenn es sich um ein separates Paket von der Kernplattform handelt.
<uses-library android:name="android.test.runner" />

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

android:targetPackage="android.test.example.helloworld"

Vielleicht haben Sie bemerkt, dass das targetPackage hier dasselbe deklariert ist wie das Das Attribut package wurde im manifest-Tag dieser Datei deklariert. Wie bereits erwähnt, Testgrundlagen sind Instrumentierungstests in der Regel zum Testen von Framework-APIs vorgesehen, daher ist es für ein spezifisches Anwendungspaket haben, also ein anderes Programm.

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

Für diese komplexeren Fälle müssen Sie auch eine Testkonfiguration für das Test-Harnisch von Android, Handelsföderation.

In der Testkonfiguration können spezielle Geräteeinrichtungsoptionen und Standardeinstellungen für die Bereitstellung der Testklasse. Ein Beispiel finden Sie unter /platform_testing/tests/example/instrumentation/AndroidTest.xml

Der Einfachheit halber finden Sie hier eine Übersicht:

<configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <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="HelloWorldTests.apk"/>
</target_preparer>

Damit wird die Trade Federation angewiesen, die HelloWorldTests.apk auf dem Ziel- mit einem angegebenen target_preparer. Es gibt viele Programmierer, den Entwicklern in der Handelsföderation zur Verfügung. das Gerät vor der Testausführung ordnungsgemäß eingerichtet ist.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

Gibt die Testklasse der Handelsföderation an, die zum Ausführen des Tests und übergibt das Paket auf dem Gerät, das ausgeführt werden soll, Framework, in diesem Fall JUnit.

Weitere Informationen finden Sie unter 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. Ein Beispiel finden Sie unter /platform_testing/tests/example/instrumentation/src/android/test/example/berücksichtigt/HelloWorldTest.java

Testmuster sind in der Regel spezifisch für Komponententeams, aber es gibt einige allgemein nützliche Nutzungsmuster.

@RunWith(JUnit4.class)
public class HelloWorldTest {

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 JUnit4-Test ausgeführt werden soll.

    @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...

Die Annotationen @Before und @After werden für Methoden von JUnit4 verwendet, um Einrichtung vor und nach dem Teardown. Gleichermaßen haben auch die @BeforeClass- und @AfterClass-Annotationen werden für Methoden von JUnit4 verwendet, um die Einrichtung vor dem Ausführen aller Tests in einer Testklasse und anschließend das Herunterfahren. Das Feld Die Einrichtungs- und Teardown-Methoden für den Klassenbereich müssen statisch sein. Bei den Testmethoden muss der Methodenname im Gegensatz zu früheren JUnit-Versionen nicht mehr mit test beginnen. Stattdessen muss jede Methode mit @Test annotiert werden. Wie gewohnt müssen Testmethoden öffentlich sein, keinen Rückgabewert angeben, keine Parameter annehmen und dürfen Ausnahmen auslösen.

Zugriff auf Instrumentierungsklassen

Auch wenn es im einfachen Hello World-Beispiel nicht erwähnt wird, ist es recht üblich, Android-Test erfordert Zugriff auf Instrumentation-Instanz: Dies ist die Kern-API Schnittstelle mit Zugriff auf Anwendungskontexte, Aktivitätslebenszyklus Test-APIs und mehr.

Da für die JUnit4-Tests keine gemeinsame Basisklasse erforderlich ist, erforderlich, um Instrumentation-Instanz über InstrumentationTestCase#getInstrumentation(), der neue Test-Runner verwaltet es über InstrumentationRegistry in dem das kontext- und umgebungsbezogene Szenario gespeichert sind.

Rufen Sie einfach die statische Methode auf, um auf die Instanz der Klasse Instrumentation zuzugreifen getInstrumentation() im InstrumentationRegistry-Kurs:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

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.