Dies ist eine kurze Einführung in die Testzuordnung und eine Erklärung, wie Sie mit der Konfiguration von Tests im Open-Source-Projekt für Android (AOSP) beginnen.
Testzuordnung
Die Testzuordnung ist ein Gerrit-basierter Ansatz, mit dem Entwickler Regeln für Tests vor und nach dem Einreichen direkt im Android-Quellcodebaum 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.
Atest kann die TEST_MAPPING Dateien verwenden, um Tests vor dem Einreichen in den
zugehörigen Verzeichnissen auszuführen. Mit der Testzuordnung können Sie die gleichen Tests zu Prüfungen vor dem Einreichen hinzufügen, ohne den Android-Quellcodebaum wesentlich zu ändern.
Beispiele:
Tests vor dem Einreichen zu
TEST_MAPPINGfürservices.corehinzufügenTests vor dem Einreichen zu
TEST_MAPPINGfürtools/dextermit Importen hinzufügen
Bei der Testzuordnung wird das Trade Federation (TF)-Test-Framework für die Testausführung und die Berichterstellung zu den Ergebnissen verwendet.
Testgruppen definieren
Bei der Testzuordnung werden Tests mit einer Testgruppe gruppiert. Der Name einer Testgruppe kann eine beliebige String sein. Beispielsweise kann presubmit der Name einer Gruppe von Tests sein, die ausgeführt werden, wenn Änderungen validiert werden. Und postsubmit kann für die Tests verwendet werden, mit denen die Builds validiert werden, nachdem Änderungen zusammengeführt wurden.
Regeln für Build-Skripts für Pakete
Damit das Trade Federation-Test-Framework
Testmodule für einen bestimmten Build ausführen kann, muss für diese Module für Soong test_suites oder für Make LOCAL_COMPATIBILITY_SUITE auf eine der folgenden beiden Suiten festgelegt sein:
general-testsist für Tests, die nicht von gerätespezifischen Funktionen abhängen (z. B. herstellerspezifische Hardware, die die meisten Geräte nicht haben). Die meisten Tests sollten sich in der Suitegeneral-testsbefinden, auch wenn sie spezifisch für eine ABI oder Bitanzahl oder Hardwarefunktionen wie HWASan sind (für jede ABI gibt es ein separatestest_suites-Ziel) und auch wenn sie auf einem Gerät ausgeführt werden müssen.device-testsist für Tests, die von gerätespezifischen Funktionen abhängen. Diese Tests befinden sich in der Regel untervendor/. Gerätespezifisch bezieht sich nur auf Funktionen, die für ein Gerät eindeutig sind. Dies gilt sowohl für JUnit- als auch für GTest-Tests (die in der Regel alsgeneral-testsgekennzeichnet 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 Test-Suite konfigurieren
Damit ein Test in einer Testsuite ausgeführt werden kann, muss er folgende Voraussetzungen erfüllen:
- Er darf keinen Build-Anbieter haben.
- Er muss nach Abschluss bereinigt werden, z. B. durch Löschen aller temporären Dateien, die während des Tests generiert wurden.
- Er muss die Systemeinstellungen auf den Standard- oder Originalwert zurücksetzen.
Er sollte nicht davon ausgehen, dass sich ein Gerät in einem bestimmten Zustand befindet, z. B. dass Root-Berechtigungen verfügbar sind. Für die meisten Tests sind keine Root-Berechtigungen erforderlich. Wenn für einen Test Root-Berechtigungen erforderlich sind, muss dies mit
RootTargetPreparerin der DateiAndroidTest.xmlangegeben 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 Prüfungen vor dem Einreichen ausgeführt werden, wenn Dateien in diesem Verzeichnis oder einem seiner Unterverzeichnisse geändert werden.
Beispiel
Hier ist eine Beispiel-TEST_MAPPING-Datei (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. Beachten Sie, dass im Feld name nicht die Klasse name oder die Testmethode name verwendet werden kann. Verwenden Sie Optionen wie include-filter, um die auszuführenden Tests einzugrenzen. Beispiel für die Verwendung von
include-filter sample usage.
Die Einstellung host eines Tests gibt an, ob der Test ein geräteloser Test ist, der auf dem Host ausgeführt wird. Der Standardwert ist false. Das bedeutet, dass für die Ausführung des Tests 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 übereinstimmen (relativ zum Verzeichnis, das die TEST_MAPPING-Datei enthält). Im Beispiel wird der
Test CtsWindowManagerDeviceTestCases nur vor dem Einreichen ausgeführt, wenn eine Java-Datei
mit Window oder Activity beginnt und sich im selben Verzeichnis wie die
TEST_MAPPING-Datei oder in einem ihrer Unterverzeichnisse befindet. Die Backslashes (\) müssen
maskiert werden, da sie sich in einer JSON-Datei befinden.
Mit dem Attribut imports können Sie Tests in anderen TEST_MAPPING-Dateien einbeziehen, ohne den Inhalt zu kopieren. Die TEST_MAPPING-Dateien in den übergeordneten Verzeichnissen des importierten Pfads werden ebenfalls einbezogen. Die Testzuordnung unterstützt verschachtelte Importe. Das bedeutet, dass zwei TEST_MAPPING-Dateien einander importieren können und die Testzuordnung die einbezogenen 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 Option handling in Tradefed.
TEST_MAPPING-Validierungen
Wenn Sie Änderungen einreichen, die TEST_MAPPING-Dateien ändern, werden Prüfungen vor dem Einreichen ausgeführt, um die Richtigkeit zu gewährleisten:
- Validierung von Dateimustern:Stellt sicher, dass alle regulären Ausdrücke in
file_patternsmit mindestens einer Datei im Repository übereinstimmen. Veraltete Muster, die mit keiner Datei übereinstimmen, führen dazu, dass die Prüfung fehlschlägt. - Validierung zur Build-Zeit:Validierungswarnungen zur Build-Zeit, die vom Build erfasst werden, werden bei der Prüfung vor dem Einreichen für Haupt-Branches zu blockierenden Fehlern. Häufige Warnungen sind:
- Nicht vorhandene Module:Verweis auf einen Testmodulnamen, der in der Codebasis nicht vorhanden ist, z. B. wenn der Name einen Tippfehler enthält.
- Ungültige Importe:Verweispfade in
imports, die nicht vorhanden sind oder keineTEST_MAPPING-Datei enthalten. - Schemaprobleme:Verwendung nicht unterstützter Schlüssel oder fehlerhafter Strukturen in der JSON-Konfiguration.
Tests mit Atest ausführen
So führen Sie die Regeln für Tests vor dem Einreichen lokal aus:
- Wechseln Sie zu dem Verzeichnis, das die
TEST_MAPPING-Datei enthält. Führen Sie diesen Befehl aus:
atest
Alle Tests vor dem Einreichen, die in den TEST_MAPPING-Dateien des aktuellen Verzeichnisses und seiner übergeordneten Verzeichnisse konfiguriert sind, werden ausgeführt. Atest sucht und führt zwei Tests vor dem Einreichen aus (A und B).
Dies ist die einfachste Möglichkeit, Tests vor dem Einreichen in TEST_MAPPING-Dateien im aktuellen Arbeitsverzeichnis (Current Working Directory, CWD) und in übergeordneten Verzeichnissen auszuführen. Atest sucht und verwendet die TEST_MAPPING-Datei im CWD und in allen übergeordneten Verzeichnissen.
Quellcode strukturieren
Dieses Beispiel zeigt, wie Sie TEST_MAPPING-Dateien im gesamten Quellcodebaum 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, um Tests in TEST_MAPPING-Dateien in diesem Verzeichnis auszuführen. Mit dem folgenden Befehl werden zwei Tests ausgeführt (A, B):
atest --test-mapping src/project_1
Regeln für Tests nach dem Einreichen ausführen
Mit diesem Befehl können Sie auch die Regeln für Tests nach dem Einreichen ausführen, die in TEST_MAPPING in src_path (Standard ist CWD) und in den übergeordneten Verzeichnissen definiert sind:
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 für die kein Gerät erforderlich ist. Ohne diese Option führt Atest beide Tests aus, sowohl die, für die ein Gerät erforderlich ist, als auch die, die auf einem Host ausgeführt werden und für die kein Gerät erforderlich ist. Die Tests werden in zwei separaten Suiten ausgeführt:
atest [--test-mapping] --host
Testgruppen identifizieren
Sie können Testgruppen im Atest-Befehl angeben. Mit dem folgenden Befehl werden alle postsubmit-Tests ausgeführt, die sich auf Dateien im Verzeichnis src/project_1 beziehen. Dieses Verzeichnis enthält nur einen Test (C).
Alternativ können Sie :all verwenden, um alle Tests unabhängig von der Gruppe auszuführen. Mit dem folgenden Befehl werden vier Tests ausgeführt (A, B, C, X):
atest --test-mapping src/project_1:all
Unterverzeichnisse einbeziehen
Standardmäßig werden beim Ausführen von Tests in TEST_MAPPING mit Atest nur Tests vor dem Einreichen ausgeführt, die in der TEST_MAPPING-Datei im CWD (oder im angegebenen Verzeichnis) und in den übergeordneten Verzeichnissen konfiguriert sind. 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 führt Atest nur Test A aus. Mit der Option --include-subdir führt Atest zwei Tests aus (A, B).
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 vorab in ein gültiges JSON-Format ohne Kommentare. Damit die JSON-Datei übersichtlich bleibt, wird nur das Kommentarformat // auf Zeilenebene unterstützt.
Beispiel:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}