To krótkie wprowadzenie do mapowania testów i wyjaśnienie, jak rozpocząć konfigurowanie testów w projekcie Android Open Source Project (AOSP).
Informacje o mapowaniu testów
Test mapping to oparte na Gerrit podejście, które umożliwia deweloperom tworzenie reguł testów przed zatwierdzeniem i po zatwierdzeniu bezpośrednio w drzewie źródłowym Androida. Decyzje dotyczące gałęzi i urządzeń, które mają być testowane, pozostawia się infrastrukturze testowej.
Definicje mapowania testów 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 kontroli przed przesłaniem przy minimalnych zmianach w drzewie źródłowym Androida.
Oto przykłady:
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
Testowanie mapowania opiera się na platformie testowej Trade Federation (TF), która służy do przeprowadzania testów i raportowania wyników.
Definiowanie grup testowych
Testuj testy grup mapowania za pomocą grupy testowej. Nazwa grupy testowej może być dowolnym ciągiem znaków. Na przykład presubmit może być nazwą grupy testów, które mają być uruchamiane podczas weryfikacji zmian. Postsubmit to testy używane do weryfikowania kompilacji po scaleniu zmian.
Reguły skryptu kompilacji pakietu
Aby platforma testowa Trade Federation mogła uruchamiać moduły testowe dla danej kompilacji, moduły te muszą mieć ustawioną wartość test_suites
dla Soong lub LOCAL_COMPATIBILITY_SUITE
dla Make w jednym z tych 2 zestawów:
general-tests
jest przeznaczony do testów, które nie zależą od funkcji specyficznych dla urządzenia (takich jak sprzęt specyficzny dla dostawcy, którego większość urządzeń nie ma). Większość testów powinna znajdować się w pakieciegeneral-tests
, nawet jeśli są one specyficzne dla jednego interfejsu ABI, liczby bitów lub funkcji sprzętowych, takich jak HWASan (dla każdego interfejsu ABI jest osobny celtest_suites
), a nawet jeśli muszą być uruchamiane na urządzeniu.device-tests
– w przypadku testów, które zależą od funkcji konkretnego urządzenia. Zwykle te testy znajdują się w sekcjivendor/
. Device-specific odnosi się tylko do funkcji, które są unikalne dla danego urządzenia, więc 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 uruchamiania w pakiecie testów
Aby test mógł zostać przeprowadzony w ramach zestawu testów:
- Nie może mieć dostawcy kompilacji.
- Po zakończeniu testu musi posprzątać, np. usunąć wszystkie pliki tymczasowe wygenerowane podczas testu.
- Ustawienia systemowe muszą zostać zmienione na domyślne lub pierwotne.
Nie należy zakładać, że urządzenie jest w określonym stanie, np. gotowe do zrootowania. Większość testów nie wymaga uprawnień roota. Jeśli test wymaga dostępu do roota, 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 pokrycia testami dodaj TEST_MAPPING
plik JSON
podobny do przykładu. Te reguły zapewniają, że testy są uruchamiane w ramach weryfikacji przed przesłaniem, gdy w tym katalogu lub w dowolnym z jego podkatalogów zostaną zmienione jakiekolwiek pliki.
Postępuj zgodnie z przykładem
Oto przykładowy plik TEST_MAPPING
(w formacie JSON, ale z obsługą komentarzy):
{
"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 testowych znajdziesz w artykule Określanie grup testowych.
Wartość atrybutu name
może zawierać nazwę modułu testowego lub nazwę testu integracyjnego Trade Federation (ścieżkę do pliku XML testu, np. uiautomator/uiautomator-demo
). Pamiętaj, że pole name
nie może używać klasy name
ani metody testowej name
. Aby zawęzić zakres testów do uruchomienia, użyj opcji takich jak include-filter
. Zobacz include-filter
przykłady użycia.
Ustawienie host
testu wskazuje, czy jest to test bez urządzenia
uruchamiany na hoście. Wartością domyślną jest false
, co oznacza, że test wymaga urządzenia do uruchomienia. Obsługiwane typy testów to HostGTest
w przypadku plików binarnych 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ędem katalogu zawierającego plik TEST_MAPPING
). W przykładzie test CtsWindowManagerDeviceTestCases
jest uruchamiany przed przesłaniem tylko wtedy, gdy plik Java zaczyna się od Window
lub Activity
i znajduje się w tym samym katalogu co plik TEST_MAPPING
lub w jednym z jego podkatalogów. Znaki ukośnika odwrotnego (\) muszą być poprzedzone znakiem ucieczki, ponieważ znajdują się w pliku JSON.
Atrybut imports
umożliwia uwzględnianie testów w innych plikach TEST_MAPPING
bez kopiowania treści. Uwzględniane są też TEST_MAPPING
pliki w folderach nadrzędnych importowanej ścieżki. Test mapping umożliwia importowanie zagnieżdżone, co oznacza, że 2 pliki TEST_MAPPING
mogą się wzajemnie importować, a test mapping może scalać zawarte w nich testy.
Atrybut options
zawiera dodatkowe opcje wiersza poleceń Tradefed.
Aby uzyskać pełną listę dostępnych opcji danego testu, uruchom:
tradefed.sh run commandAndExit [test_module] --help
Więcej informacji o działaniu opcji znajdziesz w artykule Obsługa opcji w Tradefed.
Przeprowadzanie testów za pomocą narzędzia Atest
Aby uruchomić lokalnie reguły testów przed przesłaniem:
- Przejdź do katalogu zawierającego plik
TEST_MAPPING
. Uruchom polecenie:
atest
Uruchamiane są wszystkie testy przed przesłaniem skonfigurowane w plikach TEST_MAPPING
bieżącego katalogu i jego katalogów nadrzędnych. Atest lokalizuje i uruchamia 2 testy
przed przesłaniem (A i B).
Jest to najprostszy sposób na uruchomienie testów przed przesłaniem w TEST_MAPPING
plikach w bieżącym katalogu roboczym i katalogach nadrzędnych. Atest
lokalizuje i używa pliku TEST_MAPPING
w bieżącym katalogu roboczym i we wszystkich jego katalogach nadrzędnych.
Strukturyzowanie kodu źródłowego
Ten przykład pokazuje, jak skonfigurować pliki TEST_MAPPING
w drzewie źródłowym:
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 określić katalog docelowy, w którym mają być uruchamiane testy w plikach TEST_MAPPING
. To polecenie uruchamia 2 testy (A, B):
atest --test-mapping src/project_1
Uruchamianie reguł testowych po przesłaniu
Możesz też użyć tego polecenia, aby uruchomić reguły testu po przesłaniu zdefiniowane w TEST_MAPPING
w src_path
(domyślnie CWD) i jego katalogach nadrzędnych:
atest [--test-mapping] [src_path]:postsubmit
Uruchamiaj tylko testy, które nie wymagają urządzenia
W przypadku narzędzia Atest możesz użyć opcji --host
, aby uruchamiać tylko te testy skonfigurowane na hoście, które nie wymagają urządzenia. Bez tej opcji Atest uruchamia oba rodzaje testów: te, które wymagają urządzenia, i te, które działają na hoście i nie wymagają urządzenia. Testy są przeprowadzane w 2 osobnych zestawach:
atest [--test-mapping] --host
Identyfikowanie grup testowych
Grupy testowe możesz określić w poleceniu Atest. To polecenie uruchamia wszystkie testy postsubmit
związane z plikami w katalogu src/project_1
, który zawiera tylko 1 test (C).
Możesz też użyć instrukcji :all
, aby uruchomić wszystkie testy niezależnie od grupy. 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 uruchamianie tylko testów wstępnych skonfigurowanych w pliku TEST_MAPPING
w bieżącym katalogu roboczym (lub w podanym katalogu) i jego katalogach nadrzędnych. Jeśli chcesz uruchomić testy we wszystkichTEST_MAPPING
plikach w podkatalogach, użyj opcji --include-subdir
, aby wymusić uwzględnienie tych testów w Atest.
atest --include-subdir
Bez opcji --include-subdir
Atest uruchamia tylko test A. W przypadku opcji --include-subdir
Atest przeprowadza 2 testy (A, B).
Komentarz na poziomie wiersza jest obsługiwany
Możesz dodać komentarz do formatu //
na poziomie wiersza, aby uzupełnić TEST_MAPPING
plik o opis ustawienia.
ATest i Federacja Handlowa
przetwarzają wstępnie 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"
}
]
}