Ta kategoria testów z instrumentacją nie różni się zbytnio od testów kierowanych na zwykłe aplikacje na Androida. Warto pamiętać, że testowa aplikacja zawierająca instrumentację musi być podpisana tym samym certyfikatem co aplikacja, na którą jest kierowana.
W tym przewodniku zakładamy, że masz już pewną wiedzę na temat przepływu pracy w drzewie źródeł platformy. Jeśli nie, zapoznaj się z wymaganiami. W tym przykładzie omawiamy tworzenie nowego testu pomiarowego z docelowym zestawem pakietów ustawionym na własny pakiet aplikacji testowej. Jeśli nie znasz tego zagadnienia, przeczytaj wprowadzenie do testowania platformy.
W tym przewodniku jako przykład użyto tego testu:
- frameworks/base/packages/Shell/tests
Zalecamy, aby przed dalszą pracą przejrzeć kod.
Wybierz lokalizację źródłową
Testowanie pomiarów będzie kierowane na aplikację, dlatego zgodnie z konwencją kod źródłowy testu należy umieścić w katalogu tests
w katalogu głównym katalogu źródłowego komponentu w drzewie źródłowym platformy.
Więcej informacji o lokalizacji źródła znajdziesz w pełnym przykładzie testów samoinstruowania.
Plik manifestu
Podobnie jak zwykła aplikacja, każdy moduł testu instrumentacji wymaga pliku manifestu. Jeśli nadasz plikowi nazwę AndroidManifest.xml
i przekażesz go jako Android.mk
dla testowego modułu, zostanie on automatycznie uwzględniony w pliku make BUILD_PACKAGE
.
Przed dalszymi działaniami zdecydowanie zalecamy zapoznanie się z omówieniem pliku manifestu aplikacji.
Znajdziesz tu omówienie podstawowych elementów pliku manifestu i ich funkcji.
Najnowszą wersję pliku manifestu dla przykładowej zmiany w gerrit można znaleźć tutaj: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml
Dla wygody użytkownika zamieszczamy zrzut ekranu:
<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>
Wybrane uwagi dotyczące 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 używa platforma aplikacji na Androida do identyfikowania aplikacji (w tym kontekście: Twojej 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, musisz użyć innej nazwy pakietu. Jedną z popularnych konwencji jest dodanie sufiksu .test
.
Co więcej, atrybut package
jest taki sam jak zwracany przez ComponentName#getPackageName()
, a także taki sam, którego używasz do interakcji z różnymi podrzędnymi poleceniami pm
za pomocą adb shell
.
Pamiętaj też, że chociaż nazwa pakietu jest zwykle w tym samym stylu co nazwa pakietu Java, w istocie ma z nią niewiele wspólnego. Innymi słowy, pakiet aplikacji (lub testu) może zawierać klasy o dowolnych nazwach pakietów, ale z drugiej strony możesz postawić na prostotę i użyć w aplikacji lub teście nazwy pakietu Java na najwyższym poziomie identycznej z nazwą pakietu aplikacji.
<uses-library android:name="android.test.runner" />
Jest to wymagane w przypadku wszystkich testów Instrumentation, ponieważ powiązane klasy są pakowane w oddzielnym pliku biblioteki JAR platformy, co wymaga dodatkowych wpisów classpath, gdy pakiet testów jest wywoływany przez platformę aplikacji.
android:targetPackage="com.android.shell"
W ten sposób ustawiasz docelowy pakiet narzędzi na com.android.shell
.
Gdy instrumentacja zostanie wywołana za pomocą polecenia am instrument
, framework ponownie uruchomi proces com.android.shell
i wstrzyknie do niego kod instrumentacji na potrzeby wykonania testu. Oznacza to też, że kod testowy będzie miał dostęp do wszystkich instancji klasy działających w testowanej aplikacji i może manipulować stanem w zależności od dostępnych haka testowego.
Prosty plik konfiguracji
Każdy nowy moduł testowy musi mieć plik konfiguracji, który kieruje system 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 na podstawie Soong. Więcej informacji znajdziesz w sekcji Prosta konfiguracja testu.
złożony plik konfiguracji,
W przypadku bardziej złożonych testów musisz też napisać plik konfiguracji testów dla testowego zestawu narzędzi Androida, Trade Federation.
Konfiguracja testu może określać specjalne opcje konfiguracji urządzenia i domyślne argumenty do przekazania do klasy testu.
Najnowszą wersję pliku konfiguracyjnego przykładowej zmiany w gerrite można znaleźć w folderze: frameworks/base/packages/Shell/tests/AndroidTest.xml
Dla wygody użytkownika zamieszczamy zrzut ekranu:
<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>
Oto kilka uwag na temat pliku konfiguracji testu:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk"/>
</target_preparer>
To polecenie mówi Federacji Handlowej, aby zainstalowała plik ShellTests.apk na urządzeniu docelowym za pomocą określonego parametru target_preparer. W ramach Trade Federation deweloperzy mają do dyspozycji wiele narzędzi do przygotowywania urządzeń, które można wykorzystać do sprawdzenia, czy urządzenie jest prawidłowo skonfigurowane 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ę testu Trade Federation, której należy użyć do wykonania testu, oraz przekazuje pakiet na urządzenie, na którym ma być wykonany, oraz testowy framework, którym w tym przypadku jest JUnit.
Więcej informacji o konfiguracjach testowych modułów
Funkcje JUnit4
Korzystanie z biblioteki android-support-test
jako test runnera umożliwia stosowanie nowych klas testów w stylu JUnit4, a przykładowa zmiana w Gerrit zawiera bardzo podstawowe użycie jej funkcji.
Najnowszy kod źródłowy przykładowej zmiany w 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, istnieją pewne wzorce, które są przydatne na ogół.
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {
Istotną różnicą w JUnit4 jest to, że testy nie muszą już dziedziczyć z ogólnej klasy testów podstawowych. Zamiast tego piszesz testy w zwykłych klasach Java i używasz adnotacji, aby wskazać określone ustawienia testu i ograniczenia. W tym przykładzie wskazujemy, że ta klasa powinna być uruchamiana jako test JUnit4 na Androida.
Adnotacja @SmallTest
określa rozmiar testu dla całej klasy testu: wszystkie metody testu dodane do tej klasy testu dziedziczą tę adnotację rozmiaru testu.
Przygotowanie klasy testu przed testem, rozmontowanie po teście i rozmontowanie klasy testu po teście: podobne do metod setUp
i tearDown
w JUnit4.
Adnotacja Test
służy do adnotowania rzeczywistego testu.
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
Adnotacja @Before
jest używana przez JUnit4 w metodach do konfigurowania wstępnego testowania.
W tym przykładzie nie jest używany, ale @After
służy do testowania po demontażu.
Analogicznie adnotacje @BeforeClass
i @AfterClass
mogą być używane w metodach JUnit4 do konfigurowania przed wykonaniem wszystkich testów w klasie testów, a potem do jej rozkładania. Pamiętaj, że metody konfiguracji i rozwiązywania na poziomie klasy muszą być statyczne.
W odróżnieniu od wcześniejszych wersji JUnit nazwy metod testów nie muszą już zaczynać się od test
. Każda z nich musi być opatrzona adnotacją @Test
. Jak zwykle metody testów muszą być publiczne, nie mogą deklarować wartości zwracanej, nie mogą przyjmować parametrów i mogą zgłaszać wyjątki.
Context context = InstrumentationRegistry.getTargetContext();
Testy JUnit4 nie wymagają już wspólnej klasy bazowej, więc nie trzeba uzyskiwać instancji Context
za pomocą getContext()
ani getTargetContext()
za pomocą metod klasy bazowej. Nowy testujący zarządza nimi za pomocą InstrumentationRegistry
, gdzie przechowywany jest kontekst i ustawienia środowiska utworzone przez ramkę pomiarową. W ramach tego zajęć możesz też wykonywać połączenia na:
getInstrumentation()
: instancja klasyInstrumentation
getArguments()
: argumenty wiersza poleceń przekazane doam instrument
za pomocą-e <key> <value>
Kompilowanie i testowanie lokalnie
W przypadku najczęstszych zastosowań użyj poświadczenia.
W bardziej złożonych przypadkach wymagających bardziej zaawansowanych dostosowań postępuj zgodnie z instrukcjami dotyczącymi implementacji.