Przykład kierowania aplikacji

Ta kategoria testów oprzyrządowania nie różni się zbytnio od tych przeznaczonych dla zwykłych aplikacji na Androida. Warto zauważyć, że aplikacja testowa, która zawierała oprzyrządowanie, musi być podpisana tym samym certyfikatem, co aplikacja, na którą jest przeznaczona.

Zauważ, że w tym przewodniku założono, że masz już pewną wiedzę na temat przepływu pracy drzewa źródłowego platformy. Jeśli nie, zapoznaj się z Wymaganiami . Opisany tutaj przykład to pisanie nowego testu oprzyrządowania z pakietem docelowym ustawionym we własnym pakiecie aplikacji testowej. Jeśli nie znasz tej koncepcji, przeczytaj wprowadzenie do testowania platformy .

W tym przewodniku wykorzystano następujący test, który służy jako próbka:

  • frameworki/baza/pakiety/Shell/testy

Zaleca się najpierw przejrzeć kod, aby uzyskać przybliżone wrażenie przed kontynuowaniem.

Decydowanie o lokalizacji źródłowej

Ponieważ test oprzyrządowania będzie skierowany do aplikacji, konwencja polega na umieszczeniu testowego kodu źródłowego w katalogu tests w katalogu głównym katalogu źródłowego składnika w drzewie źródłowym platformy.

Zobacz więcej dyskusji na temat lokalizacji źródła w kompletnym przykładzie, aby zapoznać się z testami z wykorzystaniem samodzielnego oprzyrządowania .

Plik manifestu

Podobnie jak w przypadku zwykłej aplikacji, każdy moduł testowania oprzyrządowania wymaga pliku manifestu. Jeśli nazwiesz plik jako AndroidManifest.xml i podasz go obok Android.mk dla testowego modułu t, zostanie on dołączony automatycznie przez core makefile BUILD_PACKAGE .

Zanim przejdziesz dalej, zdecydowanie zalecamy najpierw zapoznać się z Omówieniem manifestu aplikacji .

Daje to przegląd podstawowych składników pliku manifestu i ich funkcji.

Najnowsza wersja pliku manifestu dla przykładowej zmiany gerrit jest dostępna pod adresem: https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml

Dla wygody dołączono migawkę:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

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

        <activity
            android:name="com.android.shell.ActionSendMultipleConsumerActivity"
            android:label="ActionSendMultipleConsumer"
            android:theme="@android:style/Theme.NoDisplay"
            android:noHistory="true"
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.shell"
        android:label="Tests for Shell" />

</manifest>

Niektóre wybierają uwagi w pliku manifestu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

Atrybut package to nazwa pakietu aplikacji: jest to unikalny identyfikator, którego struktura aplikacji systemu Android używa do identyfikowania aplikacji (lub w tym kontekście: aplikacji testowej). Każdy użytkownik w systemie może zainstalować tylko jedną aplikację o tej nazwie pakietu.

Ponieważ jest to testowy pakiet aplikacji, niezależny od testowanego pakietu aplikacji, należy użyć innej nazwy pakietu: jedną z powszechnych konwencji jest dodanie przyrostka .test .

Co więcej, ten atrybut package jest taki sam, jak ComponentName#getPackageName() , a także ten sam, którego użyłbyś do interakcji z różnymi poleceniami podrzędnymi pm za pośrednictwem adb shell .

Należy również zauważyć, że chociaż nazwa pakietu jest zwykle w tym samym stylu, co nazwa pakietu Java, w rzeczywistości ma z nią niewiele wspólnego. Innymi słowy, pakiet aplikacji (lub test) może zawierać klasy z dowolnymi nazwami pakietów, chociaż z drugiej strony możesz zdecydować się na prostotę i mieć nazwę pakietu Java najwyższego poziomu w swojej aplikacji lub test identyczny z nazwą pakietu aplikacji.

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

Jest to wymagane w przypadku wszystkich testów Instrumentacji, ponieważ powiązane klasy są pakowane w oddzielnym pliku biblioteki jar środowiska, dlatego wymaga dodatkowych wpisów ścieżki klasy, gdy pakiet testowy jest wywoływany przez środowisko aplikacji.

android:targetPackage="com.android.shell"

To ustawia pakiet docelowy instrumentacji na com.android.shell . Gdy instrumentacja jest wywoływana za pomocą polecenia am instrument , platforma ponownie uruchamia proces com.android.shell i wstrzykuje kod instrumentacji do procesu w celu wykonania testu. Oznacza to również, że kod testowy będzie miał dostęp do wszystkich instancji klas działających w testowanej aplikacji i może być w stanie manipulować stanem w zależności od ujawnionych punktów zaczepienia testowego.

Prosty plik konfiguracyjny

Każdy nowy moduł testowy musi mieć plik konfiguracyjny kierujący systemem kompilacji z metadanymi modułu, zależnościami czasu kompilacji i instrukcjami pakowania. W większości przypadków wystarcza opcja pliku Blueprint opartego na Soong. Zobacz Prosta konfiguracja testu , aby uzyskać szczegółowe informacje.

Złożony plik konfiguracyjny

W przypadku bardziej złożonych testów należy również napisać plik konfiguracji testu dla wiązki testowej Androida, Trade Federation .

Konfiguracja testowa może określać specjalne opcje konfiguracji urządzenia i domyślne argumenty, aby dostarczyć klasę testową.

Najnowsza wersja pliku konfiguracyjnego dla przykładowej zmiany gerrit jest dostępna pod adresem: frameworks/base/packages/Shell/tests/AndroidTest.xml

Dla wygody dołączono migawkę:

<configuration description="Runs Tests for Shell.">
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="ShellTests.apk" />
    </target_preparer>

    <option name="test-suite-tag" value="apct" />
    <option name="test-tag" value="ShellTests" />
    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.shell.tests" />
        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
    </test>
</configuration>

Niektóre wybierają uwagi dotyczące pliku konfiguracyjnego testu:

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

To mówi Federacji Handlowej, aby zainstalować ShellTests.apk na urządzeniu docelowym przy użyciu określonego target_preparer. W Federacji Handlowej dostępnych jest wiele programów przygotowujących cele, które można wykorzystać do upewnienia się, że urządzenie jest prawidłowo skonfigurowane przed wykonaniem testów.

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

Określa to klasę testową Federacji Handlowej, która ma być używana do wykonania testu i przechodzi w pakiecie na urządzeniu, które ma zostać wykonane, oraz framework uruchamiający testy, który w tym przypadku jest JUnit.

Zajrzyj tutaj, aby uzyskać więcej informacji na temat konfiguracji modułu testowego

Funkcje JUnit4

Korzystanie z biblioteki android-support-test jako programu uruchamiającego testy umożliwia przyjęcie nowych klas testowych w stylu JUnit4, a przykładowa zmiana gerrit zawiera bardzo podstawowe wykorzystanie jej funkcji.

Najnowszy kod źródłowy przykładowej zmiany gerrit jest dostępny pod adresem: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Chociaż wzorce testowania są zwykle specyficzne dla zespołów komponentów, istnieje kilka ogólnie przydatnych wzorców użycia.

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

Istotna różnica w JUnit4 polega na tym, że testy nie muszą już dziedziczyć ze wspólnej podstawowej klasy testowej; zamiast tego piszesz testy w zwykłych klasach Javy i używasz adnotacji, aby wskazać określone ustawienia testu i ograniczenia. W tym przykładzie instruujemy, że ta klasa powinna być uruchamiana jako test Android JUnit4.

Adnotacja @SmallTest określała rozmiar testu dla całej klasy testowej: wszystkie metody testowe dodane do tej klasy testowej dziedziczą tę adnotację o rozmiarze testu. konfiguracja klasy przed testem, likwidacja klasy po teście i likwidacja klasy po teście: podobne do metod tearDown setUp JUnit4. Adnotacja Test służy do opisywania rzeczywistego testu.

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

Adnotacja @Before jest używana w metodach JUnit4 do przeprowadzenia konfiguracji przed testem. Chociaż nie jest to używane w tym przykładzie, istnieje również @After do usuwania po teście. Podobnie adnotacje @BeforeClass i @AfterClass mogą być używane w metodach JUnit4 w celu przeprowadzenia konfiguracji przed wykonaniem wszystkich testów w klasie testowej, a następnie rozerwania. Zwróć uwagę, że konfiguracja zakresu klasy i metody rozkładania muszą być statyczne.

Jeśli chodzi o metody testowe, w przeciwieństwie do wcześniejszej wersji JUnit, nie muszą już zaczynać nazwy metody od test , zamiast tego każda z nich musi być opatrzona adnotacją @Test . Jak zwykle metody testowe muszą być publiczne, nie deklarować wartości zwracanych, nie przyjmować parametrów i mogą zgłaszać wyjątki.

        Context context = InstrumentationRegistry.getTargetContext();

Ponieważ testy JUnit4 nie wymagają już wspólnej klasy bazowej, nie ma już potrzeby uzyskiwania instancji Context za pomocą getContext() lub getTargetContext() za pomocą metod klasy bazowej; Zamiast tego nowy program uruchamiający testy zarządza nimi za pośrednictwem InstrumentationRegistry , w którym przechowywana jest konfiguracja kontekstowa i środowiskowa utworzona przez platformę oprzyrządowania. Za pośrednictwem tej klasy możesz również zadzwonić:

  • getInstrumentation() : instancja do klasy Instrumentation
  • getArguments() : argumenty wiersza poleceń przekazywane do am instrument przez -e <key> <value>

Buduj i testuj lokalnie

W najczęstszych przypadkach użyj Atest .

W przypadku bardziej złożonych przypadków wymagających większego dostosowania postępuj zgodnie z instrukcjami dotyczącymi oprzyrządowania .