Testzuordnung

Dies ist eine kurze Einführung in die Testzuordnung und eine Erklärung, wie Sie mit der Konfiguration von Tests im Android Open Source Project (AOSP) beginnen.

Testzuordnung

Test-Mapping ist ein Gerrit-basierter Ansatz, mit dem Entwickler Presubmit- und Postsubmit-Testregeln direkt im Android-Quellbaum erstellen können. Die Entscheidung, welche Branches und Geräte getestet werden sollen, wird der Testinfrastruktur überlassen. Testzuordnungsdefinitionen sind JSON-Dateien mit dem Namen TEST_MAPPING, die Sie in einem beliebigen Quellverzeichnis platzieren können.

Mit Atest können Sie die TEST_MAPPING-Dateien verwenden, um Presubmit-Tests in den zugehörigen Verzeichnissen auszuführen. Mit der Testzuordnung können Sie denselben Satz von Tests mit minimalen Änderungen im Android-Quellbaum zu Pre-Submit-Prüfungen hinzufügen.

Hier einige Beispiele:

Für die Testzuordnung wird das Trade Federation (TF)-Test-Framework für die Ausführung von Tests und die Berichterstellung zu Ergebnissen verwendet.

Testgruppen definieren

Testen Sie die Zuordnungsgruppentests mit einer Testgruppe. Der Name einer Testgruppe kann ein beliebiger String sein. presubmit kann beispielsweise der Name einer Gruppe von Tests sein, die beim Validieren von Änderungen ausgeführt werden sollen. Postsubmit kann die Tests umfassen, mit denen die Builds nach dem Zusammenführen von Änderungen validiert werden.

Regeln für das Paket-Build-Skript

Damit das Trade Federation-Test-Harness Testmodule für einen bestimmten Build ausführen kann, muss für diese Module ein test_suites für Soong oder ein LOCAL_COMPATIBILITY_SUITE für Make für eine der beiden folgenden Suiten festgelegt sein:

  • general-tests ist für Tests vorgesehen, die nicht von gerätespezifischen Funktionen abhängen, z. B. von anbieterspezifischer Hardware, die die meisten Geräte nicht haben. Die meisten Tests sollten sich in der general-tests-Suite befinden, auch wenn sie spezifisch für eine ABI, Bitanzahl oder Hardwarefunktionen wie HWASan sind (für jede ABI gibt es ein separates test_suites-Ziel) und auch wenn sie auf einem Gerät ausgeführt werden müssen.
  • device-tests ist für Tests, die von gerätespezifischen Funktionen abhängen. Diese Tests befinden sich in der Regel unter vendor/. Gerätespezifisch bezieht sich nur auf Funktionen, die einem Gerät vorbehalten sind. Dies gilt sowohl für JUnit- als auch für GTest-Tests (die in der Regel als general-tests gekennzeichnet werden sollten, auch wenn sie ABI-spezifisch sind).

Beispiele:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

Tests für die Ausführung in einer Testsuite konfigurieren

Damit ein Test innerhalb einer Testsuite ausgeführt werden kann, muss er:

  • Es darf kein Build-Anbieter vorhanden sein.
  • Muss nach Abschluss des Tests bereinigt werden, z. B. durch Löschen aller während des Tests generierten temporären Dateien.
  • Die Systemeinstellungen müssen auf den Standard- oder Originalwert zurückgesetzt werden.
  • Gehen Sie nicht davon aus, dass sich ein Gerät in einem bestimmten Status befindet, z. B. „Root bereit“. Für die meisten Tests sind keine Root-Rechte erforderlich. Wenn für einen Test Root-Zugriff erforderlich ist, sollte dies mit RootTargetPreparer im AndroidTest.xml angegeben werden, wie im folgenden Beispiel:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

Testzuordnungsdateien erstellen

Fügen Sie für das Verzeichnis, für das eine Testabdeckung erforderlich ist, eine TEST_MAPPING-JSON-Datei hinzu, die dem Beispiel ähnelt. Diese Regeln sorgen dafür, dass die Tests bei Presubmit-Prüfungen ausgeführt werden, wenn Dateien in diesem Verzeichnis oder einem seiner Unterverzeichnisse geändert werden.

Beispiel folgen

Hier ist eine TEST_MAPPING-Beispieldatei (im JSON-Format, aber mit unterstützten Kommentaren):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Attribute festlegen

Im Beispiel sind presubmit und postsubmit die Namen der einzelnen Testgruppen. Weitere Informationen zu Testgruppen finden Sie unter Testgruppen definieren.

Sie können den Namen des Testmoduls oder den Namen des Trade Federation-Integrationstests (Ressourcenpfad zur Test-XML-Datei, z. B. uiautomator/uiautomator-demo) im Wert des Attributs name festlegen. Das Feld name kann nicht die Klasse name oder die Testmethode name verwenden. Mit Optionen wie include-filter können Sie die auszuführenden Tests eingrenzen. Beispiel für die Verwendung von include-filter

Die Einstellung host eines Tests gibt an, ob es sich um einen gerätelosen Test handelt, der auf dem Host ausgeführt wird. Der Standardwert ist false. Das bedeutet, dass für den Test ein Gerät erforderlich ist. Die unterstützten Testtypen sind HostGTest für GTest-Binärdateien und HostTest für JUnit-Tests.

Mit dem Attribut file_patterns können Sie eine Liste von regulären Ausdrücken festlegen, die mit dem relativen Pfad einer beliebigen Quellcodedatei (relativ zum Verzeichnis mit der Datei TEST_MAPPING) übereinstimmen. Im Beispiel wird der Test CtsWindowManagerDeviceTestCases nur im Presubmit ausgeführt, wenn eine Java-Datei mit Window oder Activity beginnt und sich im selben Verzeichnis wie die Datei TEST_MAPPING oder in einem ihrer Unterverzeichnisse befindet. Die umgekehrten Schrägstriche (\) müssen in Escapezeichen gesetzt werden, da sie sich in einer JSON-Datei befinden.

Mit dem Attribut imports können Sie Tests in andere TEST_MAPPING-Dateien einfügen, ohne den Inhalt zu kopieren. Die TEST_MAPPING-Dateien in den übergeordneten Verzeichnissen des importierten Pfads sind ebenfalls enthalten. Die Testzuordnung unterstützt verschachtelte Importe. Das bedeutet, dass zwei TEST_MAPPING-Dateien sich gegenseitig importieren können und die Testzuordnung die enthaltenen Tests zusammenführen kann.

Das Attribut options enthält zusätzliche Tradefed-Befehlszeilenoptionen.

Eine vollständige Liste der verfügbaren Optionen für einen bestimmten Test erhalten Sie mit folgendem Befehl:

tradefed.sh run commandAndExit [test_module] --help

Weitere Informationen zur Funktionsweise von Optionen finden Sie unter Optionen in Tradefed verarbeiten.

Tests mit Atest ausführen

So führen Sie die Presubmit-Testregeln lokal aus:

  1. Wechseln Sie zu dem Verzeichnis, das die Datei TEST_MAPPING enthält.
  2. Führen Sie den folgenden Befehl aus:

    atest
    

Alle in den TEST_MAPPING-Dateien des aktuellen Verzeichnisses und seiner übergeordneten Verzeichnisse konfigurierten Pre-Submit-Tests werden ausgeführt. Atest findet und führt zwei Tests für die Vorabprüfung aus (A und B).

Dies ist die einfachste Möglichkeit, Presubmit-Tests in TEST_MAPPING-Dateien im aktuellen Arbeitsverzeichnis und in übergeordneten Verzeichnissen auszuführen. „atest“ sucht und verwendet die Datei TEST_MAPPING im aktuellen Arbeitsverzeichnis und in allen übergeordneten Verzeichnissen.

Quellcode strukturieren

In diesem Beispiel wird gezeigt, wie Sie TEST_MAPPING-Dateien im gesamten Quellbaum konfigurieren können:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

Inhalt von src/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

Inhalt von src/project_1/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

Inhalt von src/project_2/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

Zielverzeichnisse angeben

Sie können ein Zielverzeichnis angeben, in dem Tests in TEST_MAPPING-Dateien ausgeführt werden sollen. Mit dem folgenden Befehl werden zwei Tests (A, B) ausgeführt:

atest --test-mapping src/project_1

Regeln für Tests nach der Einreichung ausführen

Sie können diesen Befehl auch verwenden, um die in TEST_MAPPING definierten Post-Submit-Testregeln in src_path (Standard: CWD) und den übergeordneten Verzeichnissen auszuführen:

atest [--test-mapping] [src_path]:postsubmit

Nur Tests ausführen, für die kein Gerät erforderlich ist

Mit der Option --host für Atest können Sie nur die Tests ausführen, die für den Host konfiguriert sind und kein Gerät erfordern. Ohne diese Option werden bei Atest sowohl Tests ausgeführt, für die ein Gerät erforderlich ist, als auch Tests, die auf einem Host ohne Gerät ausgeführt werden. Die Tests werden in zwei separaten Testgruppen ausgeführt:

atest [--test-mapping] --host

Testgruppen identifizieren

Sie können Testgruppen im Atest-Befehl angeben. Mit dem folgenden Befehl werden alle postsubmit-Tests für Dateien im Verzeichnis src/project_1 ausgeführt, das nur einen Test (C) enthält.

Alternativ können Sie :all verwenden, um alle Tests unabhängig von der Gruppe auszuführen. Mit dem folgenden Befehl werden vier Tests (A, B, C, X) ausgeführt:

atest --test-mapping src/project_1:all

Unterverzeichnisse einbeziehen

Wenn Sie Tests in TEST_MAPPING mit Atest ausführen, werden standardmäßig nur die in der Datei TEST_MAPPING im aktuellen Arbeitsverzeichnis (oder im angegebenen Verzeichnis) und in den übergeordneten Verzeichnissen konfigurierten Presubmit-Tests ausgeführt. Wenn Sie Tests in allen TEST_MAPPING-Dateien in den Unterverzeichnissen ausführen möchten, verwenden Sie die Option --include-subdir, um Atest zu zwingen, diese Tests ebenfalls einzubeziehen.

atest --include-subdir

Ohne die Option --include-subdir wird mit Atest nur Test A ausgeführt. Mit der Option --include-subdir werden mit Atest zwei Tests (A, B) ausgeführt.

Kommentare auf Zeilenebene werden unterstützt

Sie können einen Kommentar im //-Format auf Zeilenebene hinzufügen, um die TEST_MAPPING-Datei mit einer Beschreibung der folgenden Einstellung zu ergänzen. ATest und Trade Federation verarbeiten TEST_MAPPING in ein gültiges JSON-Format ohne Kommentare vor. Damit die JSON-Datei übersichtlich bleibt, wird nur der Kommentar im Format // auf Zeilenebene unterstützt.

Beispiel:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}