Mapowanie testowe

Oto krótkie wprowadzenie do mapowania testów i wyjaśnienie, jak rozpocząć konfigurowanie testów w ramach projektu Android Open Source Project (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.

Zobacz te przykłady:

Przeprowadzanie testów i raportowanie wyników korzysta z zaprzętu testów federacji handlowej (TF).

Definiowanie grup testowych

Testuj grupy 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 uruchomić 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 urządzenia (takich jak sprzęt producenta, którego nie ma większość urządzeń). Większość testów powinna być zawarta w pakiecie general-tests, nawet jeśli są one specyficzne dla jednego ABI lub funkcji sprzętowych, takich jak HWASan (dla każdego ABI jest osobny cel test_suites), a także jeśli muszą być uruchamiane na urządzeniu.
  • device-tests służy do testów, które zależą od funkcji urządzenia. Zwykle te testy znajdują się w sekcji vendor/. 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 jako general-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 zestawie testów

Aby test mógł być wykonywany w ramach zestawu testów:

  • Nie może mieć żadnego 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 musi wymagać dostępu do roota, powinien określić, że w parametrze AndroidTest.xml jest RootTargetPreparer, jak w tym przykładzie:

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

Tworzenie testowych plików mapowania

Do katalogu wymagającego zakresu testu dodaj plik JSON TEST_MAPPING podobny do przykładu. 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.

Skorzystaj z przykładu

Oto przykładowy plik TEST_MAPPING (jest on w formacie JSON 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 presubmitpostsubmit 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żna 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 cudzysłowie, ponieważ znajdują się w pliku JSON.

Atrybut imports pozwala uwzględnić testy 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 importowanie zagnieżdżonych plików, 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 uzyskać pełną listę opcji dostępnych w przypadku danego testu, uruchom polecenie:

tradefed.sh run commandAndExit [test_module] --help

Więcej informacji o tym, jak działają opcje, znajdziesz w artykule Opis obsługi opcji w Tradefed.

Przeprowadzanie testów za pomocą Atest

Aby lokalnie wykonać reguły testowania przed przesłaniem:

  1. Przejdź do katalogu z plikiem TEST_MAPPING.
  2. Uruchom to 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 wykorzystuje plik TEST_MAPPING w CWD oraz wszystkie jego katalogi nadrzędne.

Kod źródłowy struktury

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ść strony src/TEST_MAPPING:

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

Treść src/project_1/TEST_MAPPING:

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

Treść strony 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_MAPPINGsrc_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 dla Atest, aby uruchomić tylko te testy skonfigurowane dla hosta, który nie wymaga żadnego 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ć opcji :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 testy uruchamiane w TEST_MAPPING za pomocą Atest obejmują tylko testy przed przesłaniem skonfigurowane w pliku TEST_MAPPING w katalogu CWD (lub danym katalogu) i jego folderach nadrzędnych. Jeśli chcesz przeprowadzić testy we wszystkich plikach TEST_MAPPING w podkatalogach, użyj opcji --include-subdir, aby wymusić w narzędziu Atest uwzględnienie tych testów.

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ą dalej. ATest i Federacja handlu 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"
    }
  ]
}