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. Jedynym wyjątkiem jest to, że docelowy pakiet nie może być sam framework aplikacji na Androida, np. pakiet android, ponieważ prowadzi to do paradoksalnej sytuacji, w której trzeba by ponownie uruchomić framework Androida, który obsługuje funkcje systemu, 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 kierowanie 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:

W tym przykładzie omawiamy tworzenie nowego testu pomiarowego z docelowym pakietem ustawionym na 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 pojęcie o jego zawartości.

Wybierz lokalizację źródłową

Zespół ma zwykle ustalony schemat miejsc, w których należy sprawdzić kod, oraz miejsc, w których należy dodać 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 katalog główny źródła komponentu znajduje się w folderze <component source root>, większość komponentów ma pod sobą foldery srctests oraz niektóre dodatkowe pliki, takie jak Android.mk (lub podzielone na dodatkowe pliki .mk), plik manifestu AndroidManifest.xml oraz plik konfiguracji testu „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 dotyczące każdego pliku znajdziesz 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 zależy to od tego, czy plik APK jest podpisany tym samym certyfikatem co platforma główna (patrz LOCAL_CERTIFICATE w poprzedniej sekcji), ale są to 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 system, co oznacza, że pakiet wywołujący musi udostępnić identyfikator użytkownika usłudze system, jeśli jest to pakiet oddzielony od platformy podstawowej;
<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"

Zauważysz pewnie, że atrybut targetPackage jest tu zadeklarowany tak samo jak atrybut package w tagu manifest w tym 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 pakietu, 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 znajdziesz w artykule o konfiguracjach testowych 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.

Chociaż wzorce testowania są zwykle specyficzne dla zespołów komponentów, istnieją pewne wzorce, które są przydatne na ogół.

@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 dodać 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, po prostu wywołaj stałą metodę getInstrumentation() w klasie InstrumentationRegistry:

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.