Przykład testów samoinstrumentujących

Po rozpoczęciu testu instrumentacji jego pakiet docelowy to ponowne uruchomienie z wstrzykniętym kodem instrumentacji i inicjowaniem go do wykonania. Jeden wyjątkiem jest to, że pakiet docelowy nie może być aplikacją na Androida samej platformy, takiej jak pakiet android, ponieważ powoduje to jest paradoksalna sytuacja, w której konieczne jest ponowne uruchomienie platformy Androida, obsługuje funkcje systemowe, w tym samą instrumentację.

Oznacza to, że test narzędzi nie może wstrzykiwać się do Androida (czyli serwer systemu) do wykonywania zadań. Aby przetestować Androida na platformie, kod testowy może wywoływać tylko publiczne platformy API, w języku Android Interface Definition Language. AIDL, w drzewie źródłowym platformy. W przypadku tej kategorii testów nie ma sensu kierować reklam na konkretny pakiet. Dlatego w takich przypadkach zadeklarowanych do kierowania na własny pakiet aplikacji testowej, zdefiniowano we własnym tagu <manifest> AndroidManifest.xml.

W zależności od wymagań testowe pakiety aplikacji w tej kategorii mogą również:

  • Działania w pakiecie wymagane do testowania.
  • Udostępnij systemowi identyfikator użytkownika.
  • być podpisane kluczem platformy;
  • być skompilowana na podstawie źródła platformy, a nie publicznego pakietu SDK;

Ta kategoria testów instrumentacji jest czasami określana jako do autoinstrumentacji. Oto kilka przykładów testów autoinstrumentacji w: źródło platformy:

Opisanym tu przykładem jest pisanie nowego testu narzędziowego z wartością docelową ustawionym jako własny pakiet aplikacji testowej. W tym przewodniku zastosowano test i użyć go jako przykładu:

Zalecamy, aby najpierw przejrzeć kod, aby uzyskać ogólne informacje. zanim przejdziesz dalej.

Wybierz lokalizację źródłową

Zwykle Twój zespół ma już ustalony wzór miejsc do sprawdzenia w kodzie i miejscach, w których można dodawać testy. większość zespołów ma jedno repozytorium Git lub współużytkować go innym zespołom, ale mieć specjalny podkatalog zawierający kodu źródłowego komponentu.

Zakładając, że główna lokalizacja źródła komponentu znajduje się w lokalizacji <component source root>, większość komponentów ma pod nim foldery src i tests, a niektóre dodatkowe pliki, takie jak Android.mk (lub podzielone na dodatkowe pliki .mk), plik manifestu AndroidManifest.xml i testowy plik konfiguracji „AndroidTest.xml”.

Dodajesz zupełnie nowy test, więc prawdopodobnie konieczne będzie utworzenie tests obok komponentu src i wypełniając go zawartością.

W niektórych przypadkach zespół może mieć dodatkową strukturę katalogów w domenie tests z powodu konieczności łączenia różnych zestawów testów w pojedyncze pakiety APK. oraz W takim przypadku musisz utworzyć nowy podkatalog podkatalogu tests.

Niezależnie od struktury, wypełnisz katalog tests lub nowo utworzony podkatalog zawierający pliki podobne do tych instrumentation w przykładowej zmianie gerrit. Szczegóły każdego objaśniono w dalszej części tego dokumentu.

Plik manifestu

Tak jak w przypadku projektu aplikacji, każdy moduł testowania narzędzi wymaga plik manifestu o nazwie AndroidManifest.xml. Aby automatycznie uwzględnić za pomocąBUILD_PACKAGE głównego pliku Makefile, umieść go obok Android.mk.

Jeśli nie wiesz, jak korzystać z pliku AndroidManifest.xml, zapoznaj się z Omówienie pliku manifestu aplikacji

Oto przykładowy plik AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:sharedUserId="android.uid.system"
  package="android.test.example.helloworld" >

    <application>
       <uses-library android:name="android.test.runner"/>
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Kilka uwag na temat pliku manifestu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

Atrybut package to nazwa pakietu aplikacji: jest to unikalna identyfikator wykorzystywany przez platformę aplikacji na Androida do identyfikowania aplikacji (lub w tym kontekście: aplikacji testowej). Każdy użytkownik w systemie mogą zainstalować tylko jedną aplikację z tą nazwą pakietu.

Ponadto ten atrybut package jest taki sam jak atrybut ComponentName#getPackageName(). , a także tego samego, którego należy użyć do interakcji z różnymi podpunktami pm polecenia używają nazwy adb shell.

Pamiętaj, że chociaż nazwa pakietu jest zwykle w tym samym stylu jako nazwa pakietu Javy, tak naprawdę niewiele ma z nim wspólnego. W innym słowa, pakiet aplikacji (lub testowy) może zawierać klasy z dowolnym pakietem z kolei nazwy mogą być prostsze i wyjątkowe. nazwę pakietu Javy na poziomie w Twojej aplikacji lub testowa taka sama jak w aplikacji nazwę pakietu.

android:sharedUserId="android.uid.system"

Deklaruje to, że podczas instalacji plik APK powinien otrzymać atrybut ten sam identyfikator użytkownika, tj. tożsamość w czasie działania, co platformę podstawową. Pamiętaj, że jest to w zależności od tego, czy plik apk jest podpisany tym samym certyfikatem co podstawowa platforma. (zobacz LOCAL_CERTIFICATE w poprzedniej sekcji), choć są to 2 różne koncepcje:

  • niektóre uprawnienia lub interfejsy API są chronione podpisem, co wymaga takiego samego certyfikat podpisywania
  • niektóre uprawnienia lub interfejsy API wymagają tożsamości użytkownika wywołującego w system, , co wymaga, aby pakiet do wykonywania połączeń udostępniał identyfikator użytkownika system, jeśli oddzielny pakiet od samej platformy
<uses-library android:name="android.test.runner" />

Jest to wymagane we wszystkich testach z instrumentacją, ponieważ powiązane klasy są spakowane w oddzielnym pliku biblioteki JAR platformy, dlatego wymaga dodatkowych classpath, gdy pakiet testowy jest wywoływany przez platformę aplikacji.

android:targetPackage="android.test.example.helloworld"

Jak widzisz, pole targetPackage jest zadeklarowane tak samo jak Atrybut package zadeklarowany w tagu manifest tego pliku. Jak wspomniano w: podstaw testowania, ta kategoria testów z instrumentacją to zwykle jest przeznaczone do testowania interfejsów API platformy, więc nie ma zbyt dużego znaczenia dla konkretnego pakietu aplikacji, a nie tego samego.

Prosty plik konfiguracji

Każdy nowy moduł testowy musi zawierać plik konfiguracji, który umożliwia system kompilacji z metadanymi modułów, zależnościami czasu kompilowania oraz sposobem prezentacji za instrukcje. W większości przypadków opcja pliku Blueprint oparta na oprogramowaniu Soong jest wystarczająca. Więcej informacji: Prosta konfiguracja testu.

Złożony plik konfiguracji

W przypadku bardziej złożonych przypadków musisz też napisać konfigurację testową pliku danych dla jarzma testowego na Androida, Federacja handlowa.

Konfiguracja testu może określać specjalne opcje konfiguracji urządzenia i ustawienia domyślne. argumentów dostarczających klasę testową. Zobacz przykład na stronie /platform_testing/tests/example/instrumentation/AndroidTest.xml

Dla wygody podajemy tu podsumowanie:

<configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>

Uwagi na temat testowego pliku konfiguracji:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>

Dzięki temu federacja handlowa powinna zainstalować plik HelloWorldTests.apk w środowisku docelowym za pomocą określonego atrybutu target_preparer. Wiele osób przygotowujących do kierowania reklam dostępnych dla deweloperów w Federacji Handlowej. Można je wykorzystać, aby zagwarantować, sprawdź, czy urządzenie jest prawidłowo skonfigurowane przed rozpoczęciem testu.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

Określa klasę testową federacji handlowej, która ma zostać użyta do przeprowadzenia testu i przechodzi w pakiecie na urządzeniu, który ma zostać wykonany, a użytkownik wykonujący test czyli JUnit,

Więcej informacji: Testuj konfiguracje modułu.

Funkcje JUnit4

Użycie biblioteki android-support-test jako mechanizmu uruchamiania testów pozwala na wdrożenie nowych klas testowych stylu JUnit4, a przykładowa zmiana gerrit zawiera pewne bardzo podstawowe korzystanie z jego funkcji. Zobacz przykład na stronie /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java.

Wzorce testowania są zwykle typowe dla zespołów składających się z poszczególnych zespołów, i przydatnych wzorców użytkowania.

@RunWith(JUnit4.class)
public class HelloWorldTest {

Znacząca różnica w JUnit4 polega na tym, że testy nie są już wymagane dziedziczenie ze wspólnej klasy podstawowej; zamiast tego piszesz w Javie. i używać adnotacji do wskazywania określonych konfiguracji i ograniczeń testów. W w tym przykładzie, instruujemy, że ta klasa powinna zostać uruchomiona jako test JUnit4.

    @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...

Adnotacje @Before i @After są używane w metodach JUnit4 konfiguracji przed testem i po jego zakończeniu. Podobnie @BeforeClass oraz Adnotacje @AfterClass są używane w metodach JUnit4 do konfiguracji przed przeprowadzanie wszystkich testów w klasie testowej, a później usuwanie. Pamiętaj, że parametr Metody konfiguracji i usuwania w zakresie klasy muszą być statyczne. Jeśli chodzi o metody testowania, w przeciwieństwie do wcześniejszej wersji JUnit nie muszą już rozpoczynać nazwy metody. za pomocą funkcji test, zamiast tego do każdego z nich należy zastosować adnotację @Test. Jak zwykle, metody testowe muszą być publiczne, zadeklarować brak wartości zwrotnej, nie mogą przyjmować żadnych parametrów oraz może zgłaszać wyjątki.

Dostęp do klasy instrumentacji

Chociaż nie jest to omówione w podstawowym przykładzie ze światem hello, jest dość powszechne Test Androida wymagający dostępu do instancji Instrumentation: to jest podstawowy interfejs API interfejs zapewniający dostęp do kontekstu aplikacji, cyklu życia działania powiązane testowe interfejsy API i nie tylko.

Ponieważ testy JUnit4 nie wymagają już wspólnej klasy bazowej, konieczne do uzyskania instancji Instrumentation za pośrednictwem InstrumentationTestCase#getInstrumentation(), zamiast tego nowy biegacz testowy zarządza nim w usłudze InstrumentationRegistry gdzie konfiguracja kontekstowa i środowiskowa utworzona przez platformę instrumentacji zapisane.

Aby uzyskać dostęp do instancji klasy Instrumentation, wystarczy wywołać metodę statyczną getInstrumentation() na InstrumentationRegistry zajęciach:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Kompilowanie i testowanie lokalnie

W najczęstszych przypadkach użycia Atest.

W przypadku bardziej złożonych przypadków, które wymagają większych dostosowań, postępuj zgodnie z instrumentacji.