Kieruj na przykład aplikacji

Ta kategoria testów oprzyrządowania nie różni się zbytnio od tych, których celem są zwykłe aplikacje na Androida. Warto zauważyć, że aplikacja testowa zawierająca oprzyrządowanie musi być podpisana tym samym certyfikatem, co aplikacja, na którą jest przeznaczona.

Należy pamiętać, że w tym przewodniku założono, że masz już pewną wiedzę na temat przepływu pracy drzewa źródeł platformy. Jeśli nie, zapoznaj się z wymaganiami . Opisany tutaj przykład polega na pisaniu nowego testu oprzyrządowania z pakietem docelowym ustawionym w jego własnym pakiecie aplikacji testowej. Jeśli nie znasz tej koncepcji, przeczytaj wprowadzenie do testowania platformy .

W tym przewodniku jako przykład wykorzystano następujący test:

  • frameworki/baza/pakiety/Shell/testy

Zaleca się najpierw przejrzeć kod, aby uzyskać ogólne wrażenie przed kontynuowaniem.

Zdecyduj się na lokalizację źródłową

Ponieważ test oprzyrządowania będzie ukierunkowany na aplikację, konwencja polega na umieszczeniu kodu źródłowego testu w katalogu tests w katalogu głównym katalogu źródłowego komponentów w drzewie źródeł platformy.

Zobacz więcej dyskusji na temat lokalizacji źródła w kompleksowym przykładzie testów samoinstrumentujących .

Plik manifestu

Podobnie jak zwykła aplikacja, każdy moduł testowy oprzyrządowania wymaga pliku manifestu. Jeśli nazwiesz plik jako AndroidManifest.xml i podasz go obok Android.mk dla modułu testowego, zostanie on automatycznie dołączony do podstawowego pliku makefile BUILD_PACKAGE .

Przed kontynuowaniem zdecydowanie zaleca się zapoznanie się z omówieniem manifestu aplikacji .

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

Najnowszą wersję pliku manifestu dla przykładowej zmiany gerrit można uzyskać pod adresem: https://android.googlesource.com/platform/frameworks/base/+/main/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 wybrane uwagi na temat 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 używany przez platformę aplikacji systemu Android 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 pakiet aplikacji testowej, 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 zwracany przez ComponentName#getPackageName() i ten sam, którego można używać do interakcji z różnymi podpoleceniami pm za pośrednictwem adb shell .

Należy również pamiętać, że chociaż nazwa pakietu jest zazwyczaj w tym samym stylu, co nazwa pakietu Java, w rzeczywistości ma z nią niewiele wspólnego. Innymi słowy, pakiet Twojej aplikacji (lub testu) może zawierać klasy o dowolnych nazwach pakietów, chociaż z drugiej strony możesz zdecydować się na prostotę i mieć w aplikacji lub teście nazwę pakietu Java najwyższego poziomu identyczną 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ą spakowane w oddzielnym pliku biblioteki jar platformy, dlatego wymagane są dodatkowe wpisy ścieżki klas, gdy pakiet testowy jest wywoływany przez platformę aplikacji.

android:targetPackage="com.android.shell"

Spowoduje to ustawienie docelowego pakietu oprzyrządowania na com.android.shell . Po wywołaniu oprzyrządowania za pomocą polecenia am instrument platforma ponownie uruchamia proces com.android.shell i wstrzykuje kod oprzyrządowania 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 odsłoniętych haków testowych.

Prosty plik konfiguracyjny

Każdy nowy moduł testowy musi mieć plik konfiguracyjny, który będzie sterował systemem kompilacji za pomocą metadanych modułu, zależności w czasie kompilacji i instrukcji pakowania. W większości przypadków wystarczająca jest opcja pliku Blueprint oparta na Song. Aby uzyskać szczegółowe informacje, zobacz Prosta konfiguracja testu .

Złożony plik konfiguracyjny

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

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

Najnowszą wersję pliku konfiguracyjnego dla przykładowej zmiany gerrit można uzyskać 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>

Kilka wybranych uwag na temat testowego pliku konfiguracyjnego:

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

To informuje Federację Handlową, aby zainstalowała plik ShellTests.apk na urządzeniu docelowym przy użyciu określonego narzędzia target_preparer. Programiści w Federacji Handlowej mają do dyspozycji wiele narzędzi do przygotowywania celów, które można wykorzystać w celu zapewnienia prawidłowej konfiguracji urządzenia przed wykonaniem testu.

<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 klasę testową Federacji Handlowej, która ma zostać użyta do wykonania testu i przechodzi w pakiecie na urządzeniu, które ma zostać wykonane, oraz strukturę modułu uruchamiającego testy, którą w tym przypadku jest JUnit.

Więcej informacji na temat konfiguracji modułów testowych można znaleźć tutaj

Funkcje JUnit4

Użycie biblioteki android-support-test jako modułu uruchamiającego test umożliwia przyjęcie nowych klas testowych w stylu JUnit4, a przykładowa zmiana gerrita obejmuje bardzo podstawowe wykorzystanie jej funkcji.

Dostęp do najnowszego kodu źródłowego przykładowej zmiany gerrit można uzyskać pod adresem: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Chociaż wzorce testowania są zwykle specyficzne dla zespołów składowych, istnieją pewne ogólnie przydatne wzorce 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 Java i używasz adnotacji, aby wskazać konkretną konfigurację testu i ograniczenia. W tym przykładzie instruujemy, że ta klasa powinna zostać uruchomiona 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 po teście i likwidacja klasy po teście: podobne do metod setUp i tearDown w 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 w celu przeprowadzenia wstępnej konfiguracji testowej. Chociaż nie jest używany w tym przykładzie, istnieje również @After do rozrywania po teście. Podobnie, adnotacji @BeforeClass i @AfterClass można używać w metodach JUnit4 w celu przeprowadzenia konfiguracji przed wykonaniem wszystkich testów w klasie testowej, a następnie jej usunięcia. Należy pamiętać, że metody konfiguracji i usuwania zakresu klasy muszą być statyczne.

Jeśli chodzi o metody testowe, w przeciwieństwie do wcześniejszych wersji JUnit, nie muszą one już rozpoczynać 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 zwracanej, nie przyjmować żadnych parametrów i mogą zgłaszać wyjątki.

        Context context = InstrumentationRegistry.getTargetContext();

Ponieważ testy JUnit4 nie wymagają już wspólnej klasy bazowej, nie jest już konieczne uzyskiwanie instancji Context za pomocą metody getContext() lub getTargetContext() za pomocą metod klasy bazowej; zamiast tego nowy moduł uruchamiający testy zarządza nimi za pośrednictwem InstrumentationRegistry , w którym przechowywane są ustawienia kontekstowe i środowiskowe utworzone przez platformę oprzyrządowania. Za pośrednictwem tej klasy możesz także wywołać:

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

Kompiluj i testuj lokalnie

W najczęstszych przypadkach użycia użyj Atest .

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