Ten artykuł zawiera krótkie wprowadzenie do mapowania testów oraz wyjaśnienie, jak rozpocząć konfigurowanie testów w projektach typu Open Source w Androidzie (AOSP).
Informacje o mapowaniu testów
Mapowanie testów to podejście oparte na Gerricie, które pozwala deweloperom tworzyć reguły testów przed przesłaniem i po przesłaniu bezpośrednio w drzewie źródłowym Androida, a także pozostawiać infrastrukturze testowej decyzje dotyczące gałęzi i urządzeń, które mają być testowane.
Definicje testów mapowania to pliki JSON o nazwie TEST_MAPPING
, które możesz umieścić w dowolnym katalogu źródłowym.
Atest może używać plików TEST_MAPPING
do przeprowadzania testów przed przesłaniem w powiązanych katalogach. Dzięki mapowaniu testów możesz dodać ten sam zestaw testów do weryfikacji przed przesłaniem, wprowadzając minimalne zmiany w drzewie źródłowym Androida.
Zapoznaj się z tymi przykładami:
Dodawanie testów przed przesłaniem do
TEST_MAPPING
w przypadkuservices.core
Dodawanie testów przed przesłaniem do
TEST_MAPPING
w przypadkutools/dexter
za pomocą importów
Mapowanie testów polega na korzystaniu z testów Trade Federation (TF) do wykonywania testów i raportowania wyników.
Definiowanie grup testowych
Testowanie grup mapowania za pomocą grupy testowej. Nazwa grupy testów może być dowolnym ciągiem znaków. Na przykład presubmit może być nazwą grupy testów, które należy wykonać podczas sprawdzania zmian. Testy po przesłaniu mogą służyć do sprawdzania kompilacji po złączeniu zmian.
Reguły skryptu kompilacji pakietu
Aby narzędzie testowe Trade Federation mogło uruchamiać moduły testowe danej kompilacji, moduły te muszą mieć ustawioną wartość test_suites
dla Soong lub LOCAL_COMPATIBILITY_SUITE
dla Make w ramach jednego z tych pakietów:
general-tests
służy do testów, które nie zależą od funkcji dostępnych na konkretnym urządzeniu (np. sprzętu konkretnego producenta, którego nie ma większość urządzeń). Większość testów powinna być zawarta w pakieciegeneral-tests
, nawet jeśli dotyczą one konkretnego ABI, liczby bitów lub funkcji sprzętowych, takich jak HWASan (dla każdego ABI jest osobny obiekt docelowytest_suites
), a także nawet jeśli muszą być wykonywane na urządzeniu.device-tests
służy do testów, które zależą od możliwości urządzenia. Zwykle te testy znajdują się w sekcjivendor/
. Dla urządzenia odnosi się tylko do funkcji, które są unikalne dla urządzenia, dlatego dotyczy to zarówno testów JUnit, jak i testów GTest (które zwykle powinny być oznaczone jakogeneral-tests
, nawet jeśli są specyficzne dla ABI).
Przykłady:
Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests
Konfigurowanie testów do uruchomienia w pakiecie testów
Aby test mógł być wykonywany w ramach zestawu testów:
- Nie może być dostawcy kompilacji.
- Po zakończeniu testu musisz wyczyścić system, na przykład usuwając tymczasowe pliki utworzone podczas testu.
- Musisz zmienić ustawienia systemowe na domyślne lub pierwotne wartości.
Nie należy zakładać, że urządzenie jest w określonym stanie, na przykład gotowe do rootowania. Większość testów nie wymaga uprawnień roota. Jeśli test wymaga uprawnień root, należy to określić za pomocą parametru
RootTargetPreparer
wAndroidTest.xml
, jak w tym przykładzie:<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
Tworzenie testowych plików mapowania
W przypadku katalogu wymagającego testowania dodaj plik JSON TEST_MAPPING
podobny do tego. Te reguły zapewniają, że testy są uruchamiane w ramach weryfikacji przed przesłaniem, gdy w tym katalogu lub dowolnym z jego podkatalogów zostaną zmienione jakiekolwiek pliki.
Postępuj zgodnie z przykładem
Oto przykładowy plik TEST_MAPPING
(jest on w formacie JSON, ale obsługuje komentarze):
{
"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"
}
]
}
Ustawianie atrybutów
W przykładzie presubmit
i postsubmit
to nazwy poszczególnych grup testowych. Więcej informacji o grupach testów znajdziesz w artykule Definiowanie grup testów.
W wartości atrybutu name
możesz podać nazwę modułu testowego lub nazwę testu integracji z Federacją Handlową (ścieżka do zasobu do pliku XML testu, np. uiautomator/uiautomator-demo
). Pamiętaj, że w polu name
nie możesz użyć klasy name
ani metody testu name
. Aby zawęzić zakres testów do wykonania, użyj opcji takich jak include-filter
. Zobacz include-filter
przykładowe użycie.
Ustawienie host
testu wskazuje, czy jest to test bez urządzenia działający na hoście. Wartość domyślna to false
, co oznacza, że test wymaga użycia urządzenia. Obsługiwane typy testów to HostGTest
w przypadku binarek GTest i HostTest
w przypadku testów JUnit.
Atrybut file_patterns
umożliwia ustawienie listy ciągów wyrażeń regularnych do dopasowywania ścieżki względnej dowolnego pliku kodu źródłowego (względnie katalogu zawierającego plik TEST_MAPPING
). W przykładzie test CtsWindowManagerDeviceTestCases
jest wykonywany przed przesłaniem tylko wtedy, gdy plik Java zaczyna się od Window
lub Activity
, który znajduje się w tym samym katalogu co plik TEST_MAPPING
lub w jednym z jego podkatalogów. Znaki ukośnikowe (\) muszą być ujęte w znaki ucieczki, ponieważ znajdują się w pliku JSON.
Atrybut imports
umożliwia uwzględnianie testów w innych plikach TEST_MAPPING
bez kopiowania treści. Do pliku importowanego ścieżki dołączone są też pliki TEST_MAPPING
z folderów nadrzędnych. Mapowanie testów umożliwia zagnieżdżone importy, co oznacza, że 2 pliki TEST_MAPPING
mogą się nawzajem importować, a mapowanie testów może łączyć zawarte w nich testy.
Atrybut options
zawiera dodatkowe opcje wiersza poleceń Tradefed.
Aby zobaczyć pełną listę dostępnych opcji dla danego testu, wykonaj:
tradefed.sh run commandAndExit [test_module] --help
Więcej informacji o tym, jak działają opcje, znajdziesz w artykule Opracowywanie opcji w Tradefed.
Przeprowadzanie testów za pomocą Atest
Aby uruchomić reguły testowania przed przesłaniem lokalnie:
- Przejdź do katalogu zawierającego plik
TEST_MAPPING
. Uruchom polecenie:
atest
Uruchomione są wszystkie testy przed przesłaniem skonfigurowane w plikach TEST_MAPPING
w bieżącym katalogu i jego katalogach nadrzędnych. Atest znajduje i uruchamia 2 testy przed przesłaniem (A i B).
Jest to najprostszy sposób na uruchomienie testów przed przesłaniem w plikach TEST_MAPPING
w bieżącym katalogu roboczym (CWD) i katalogach nadrzędnych. Atest znajduje i używa pliku TEST_MAPPING
w katalogu CWD i wszystkich jego katalogach nadrzędnych.
Struktura kodu źródłowego
Ten przykład pokazuje, jak skonfigurować pliki TEST_MAPPING
w drzewie źródeł:
src
├── project_1
│ └── TEST_MAPPING
├── project_2
│ └── TEST_MAPPING
└── TEST_MAPPING
Treść src/TEST_MAPPING
:
{
"presubmit": [
{
"name": "A"
}
]
}
Treść src/project_1/TEST_MAPPING
:
{
"presubmit": [
{
"name": "B"
}
],
"postsubmit": [
{
"name": "C"
}
],
"other_group": [
{
"name": "X"
}
]}
Treść src/project_2/TEST_MAPPING
:
{
"presubmit": [
{
"name": "D"
}
],
"import": [
{
"path": "src/project_1"
}
]}
Określanie katalogów docelowych
Możesz podać katalog docelowy, aby uruchomić testy w plikach TEST_MAPPING
w tym katalogu. To polecenie uruchamia 2 testy (A, B):
atest --test-mapping src/project_1
Przeprowadzanie reguł testowych po przesłaniu
Możesz też użyć tego polecenia, aby uruchomić reguły testowe po przesłaniu zdefiniowane w TEST_MAPPING
w src_path
(domyślnie bieżący katalog) i jego katalogach nadrzędnych:
atest [--test-mapping] [src_path]:postsubmit
Uruchamianie tylko testów, które nie wymagają urządzenia
Możesz użyć opcji --host
w Atest, aby uruchomić tylko te testy skonfigurowane w przypadku hosta, które nie wymagają urządzenia. Bez tej opcji Atest uruchamia oba testy – te, które wymagają urządzenia, oraz te, które są wykonywane na hoście, który nie wymaga urządzenia. Testy są przeprowadzane w 2 oddzielnych zestawach:
atest [--test-mapping] --host
Identyfikowanie grup testowych
Grupy testów możesz określić w komendach Atest. Podane niżej polecenie uruchamia wszystkie testy postsubmit
dotyczące plików w katalogu src/project_1
, który zawiera tylko jeden test (C).
Możesz też użyć :all
, aby uruchomić wszystkie testy bez względu na grupę. To polecenie uruchamia 4 testy (A, B, C, X):
atest --test-mapping src/project_1:all
Uwzględnij podkatalogi
Domyślnie uruchamianie testów w TEST_MAPPING
za pomocą Atest powoduje uruchomienie tylko testów przed przesłaniem skonfigurowanych w pliku TEST_MAPPING
w katalogu CWD (lub katalogu podrzędnym) i jego folderach nadrzędnych. Jeśli chcesz uruchomić testy we wszystkich plikach TEST_MAPPING
w podfolderach, użyj opcji --include-subdir
, aby wymusić uwzględnienie tych testów przez Atest.
atest --include-subdir
Bez opcji --include-subdir
Atest wykonuje tylko test A. W przypadku opcji --include-subdir
Atest przeprowadza 2 testy (A i B).
Komentarze na poziomie wiersza
Możesz dodać komentarz w formacie //
na poziomie wiersza, aby uzupełnić plik TEST_MAPPING
o opis ustawień, które występują później.
ATest i Federacja handlowa przetwarzają TEST_MAPPING
do prawidłowego formatu JSON bez komentarzy. Aby plik JSON był przejrzysty, obsługiwany jest tylko komentarz w formacie //
na poziomie wiersza.
Przykład:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}