Bir enstrümantasyon testi başlatıldığında, hedef paketi, enstrümantasyon kodu enjekte edilerek yeniden başlatılır ve yürütme için başlatılır. Bunun bir istisnası, buradaki hedef paketin, android
paketi gibi Android uygulama çerçevesinin kendisi olamayacağıdır, çünkü bunu yapmak, Android çerçevesinin yeniden başlatılmasının gerekeceği paradoksal bir duruma yol açar; bu, aşağıdakiler de dahil olmak üzere sistem işlevlerini destekler: enstrümantasyonun kendisi.
Bu, bir enstrümantasyon testinin yürütme için kendisini Android çerçevesine, yani sistem sunucusuna enjekte edemeyeceği anlamına gelir. Android çerçevesini test etmek için test kodu yalnızca genel API yüzeylerini veya platform kaynak ağacında bulunan Android Arayüz Tanımlama Dili (AIDL) kullanılarak kullanıma sunulanları çağırabilir. Bu test kategorisi için belirli bir paketi hedeflemek anlamlı değildir. Bu nedenle, bu tür enstrümantasyonların, AndroidManifest.xml
dosyasının kendi <manifest>
etiketinde tanımlandığı gibi, kendi test uygulama paketini hedefleyecek şekilde bildirilmesi gelenekseldir.
Bu kategorideki test uygulama paketleri, gereksinimlere bağlı olarak ayrıca:
- Test için gereken paket aktiviteleri.
- Kullanıcı kimliğini sistemle paylaşın.
- Platform anahtarıyla imzalanmış olun.
- Genel SDK yerine çerçeve kaynağına göre derlenmelidir.
Bu enstrümantasyon testleri kategorisine bazen kendi kendine enstrümantasyon adı verilir. Platform kaynağındaki kendi kendine enstrümantasyon testlerinin bazı örnekleri:
Burada ele alınan örnek, kendi test uygulama paketinde belirlenen hedef paketle yeni bir enstrümantasyon testi yazmaktır. Bu kılavuzda örnek olarak aşağıdaki test kullanılmaktadır:
Devam etmeden önce kaba bir izlenim edinmek için önce koda göz atmanız önerilir.
Kaynak konumuna karar verin
Tipik olarak ekibiniz, kodun teslim edileceği yerler ve testlerin ekleneceği yerler konusunda önceden belirlenmiş bir modele sahip olacaktır. Çoğu ekibin tek bir git deposu vardır veya bir tanesini diğer ekiplerle paylaşır ancak bileşen kaynak kodunu içeren özel bir alt dizine sahiptir.
Bileşen kaynağınızın kök konumunun <component source root>
konumunda olduğunu varsayarsak, çoğu bileşenin altında src
ve tests
klasörleri bulunur ve Android.mk
(veya ek .mk
dosyalarına bölünmüş), bildirim dosyası AndroidManifest.xml
gibi bazı ek dosyalar bulunur. AndroidManifest.xml
ve test yapılandırma dosyası 'AndroidTest.xml'.
Yepyeni bir test ekleyeceğiniz için muhtemelen src
bileşeninizin yanında tests
dizinini oluşturmanız ve onu içerikle doldurmanız gerekecektir.
Bazı durumlarda, farklı test paketlerini ayrı apk'ler halinde paketleme ihtiyacından dolayı ekibiniz, tests
aşamasında olan başka dizin yapılarına sahip olabilir. Bu durumda, tests
altında yeni bir alt dizin oluşturmanız gerekecektir.
Yapıdan bağımsız olarak, tests
dizinini veya yeni oluşturulan alt dizini, örnek gerrit değişikliğindeki instrumentation
dizinindekilere benzer dosyalarla dolduracaksınız. Her dosyanın ayrıntıları bu belgenin ilerleyen kısımlarında açıklanacaktır.
Bildirim dosyası
Bir uygulama projesinde olduğu gibi, her enstrümantasyon test modülü, AndroidManifest.xml
adlı bir bildirim dosyası gerektirir. Bu dosyayı BUILD_PACKAGE
çekirdek makefile kullanarak otomatik olarak eklemek için bu dosyayı test modülünüzün Android.mk
dosyasının yanına sağlayın.
AndroidManifest.xml
dosyasına aşina değilseniz Uygulama Bildirimine Genel Bakış'a bakın
Aşağıda örnek bir AndroidManifest.xml
dosyası verilmiştir:
<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>
Bildiri dosyasındaki bazı seçilmiş açıklamalar:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
package
niteliği, uygulama paketinin adıdır: Bu, Android uygulama çerçevesinin bir uygulamayı (veya bu bağlamda: test uygulamanızı) tanımlamak için kullandığı benzersiz tanımlayıcıdır. Sistemdeki her kullanıcı o paket adı ile yalnızca bir uygulama kurabilir.
Ayrıca, bu package
özniteliği ComponentName#getPackageName()
işlevinin döndürdüğü öznitelikle aynıdır ve ayrıca adb shell
kullanan çeşitli pm
alt komutlarıyla etkileşimde bulunmak için kullanacağınız öznitelikle aynıdır.
Paket adının genellikle Java paket adıyla aynı tarzda olmasına rağmen aslında onunla çok az ilgisi olduğunu unutmayın. Başka bir deyişle, uygulama (veya test) paketiniz herhangi bir paket adına sahip sınıflar içerebilir, ancak diğer yandan basitliği tercih edebilir ve üst düzey Java paket adınızı uygulamanızda veya testinizde uygulama paket adıyla aynı tutabilirsiniz.
android:sharedUserId="android.uid.system"
Bu, kurulum sırasında bu APK dosyasına çekirdek platformla aynı kullanıcı kimliğinin, yani çalışma zamanı kimliğinin verilmesi gerektiğini belirtir. Bunun, apk'nin çekirdek platformla aynı sertifikayla imzalanmasına bağlı olduğunu unutmayın (önceki bölümde LOCAL_CERTIFICATE
bakın), ancak bunlar farklı kavramlardır:
- bazı izinler veya API'ler imza korumalıdır ve bu da aynı imzalama sertifikası gerektirir
- Bazı izinler veya API'ler, arayanın
system
kullanıcı kimliğini gerektirir; bu, çekirdek platformun kendisinden ayrı bir paketse, çağıran paketin kullanıcı kimliğinisystem
ile paylaşmasını gerektirir.
<uses-library android:name="android.test.runner" />
İlgili sınıflar ayrı bir çerçeve JAR kitaplık dosyasında paketlendiğinden bu, tüm Enstrümantasyon testleri için gereklidir, dolayısıyla test paketi uygulama çerçevesi tarafından çağrıldığında ek sınıf yolu girişleri gerektirir.
android:targetPackage="android.test.example.helloworld"
Buradaki targetPackage
, bu dosyanın manifest
etiketinde bildirilen package
özniteliğiyle aynı şekilde bildirildiğini fark etmiş olabilirsiniz. Test temelleri bölümünde belirtildiği gibi, bu enstrümantasyon testi kategorisi genellikle çerçeve API'lerini test etmeye yöneliktir, bu nedenle kendisi dışında belirli bir hedefe yönelik uygulama paketine sahip olmaları çok anlamlı değildir.
Basit yapılandırma dosyası
Her yeni test modülü, derleme sistemini modül meta verileri, derleme zamanı bağımlılıkları ve paketleme talimatlarıyla yönlendirecek bir yapılandırma dosyasına sahip olmalıdır. Çoğu durumda Soong tabanlı Blueprint dosyası seçeneği yeterlidir. Ayrıntılar için bkz. Basit Test Yapılandırması .
Karmaşık yapılandırma dosyası
Bu daha karmaşık durumlar için, Android'in test koşum takımı Trade Federasyonu için bir test yapılandırma dosyası da yazmanız gerekir.
Test konfigürasyonu, test sınıfını sağlamak için özel cihaz kurulum seçeneklerini ve varsayılan argümanları belirtebilir. /platform_testing/tests/example/instrumentation/AndroidTest.xml adresindeki örneğe bakın.
Kolaylık sağlamak için buraya bir anlık görüntü eklenmiştir:
<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>
Test yapılandırma dosyasındaki bazı seçilmiş açıklamalar:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
Bu, Ticaret Federasyonuna, belirtilen bir target_preparer kullanarak HelloWorldTests.apk dosyasını hedef cihaza yüklemesini söyler. Ticaret Federasyonu'nda geliştiricilerin kullanabileceği çok sayıda hedef hazırlayıcı vardır ve bunlar, testin yürütülmesinden önce cihazın doğru şekilde kurulduğundan emin olmak için kullanılabilir.
<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>
Bu, testi yürütmek için kullanılacak Ticaret Federasyonu test sınıfını ve yürütülecek cihazdaki pakette geçenleri ve bu durumda JUnit olan test çalıştırıcı çerçevesini belirtir.
Daha fazla bilgi için bkz. Test Modülü Yapılandırmaları .
JUnit4 özellikleri
android-support-test
kütüphanesinin test çalıştırıcısı olarak kullanılması, yeni JUnit4 tarzı test sınıflarının benimsenmesine olanak tanır ve örnek gerrit değişikliği, özelliklerinin bazı çok temel kullanımını içerir. /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java adresindeki örneğe bakın.
Test kalıpları genellikle bileşen ekiplerine özel olsa da, genel olarak bazı faydalı kullanım kalıpları da vardır.
@RunWith(JUnit4.class)
public class HelloWorldTest {
JUnit4'teki önemli bir fark, testlerin artık ortak bir temel test sınıfından miras alınmasının gerekmemesidir; bunun yerine testleri düz Java sınıflarında yazarsınız ve belirli test kurulumunu ve kısıtlamalarını belirtmek için ek açıklamalar kullanırsınız. Bu örnekte bu sınıfın JUnit4 testi olarak çalıştırılması gerektiğini anlatıyoruz.
@BeforeClass
public static void beforeClass() {
...
@AfterClass
public static void afterClass() {
...
@Before
public void before() {
...
@After
public void after() {
...
@Test
@SmallTest
public void testHelloWorld() {
...
@Before
ve @After
açıklamaları, JUnit4 tarafından test öncesi kurulum ve test sonrası sökme işlemlerini gerçekleştirmek için kullanılan yöntemlerde kullanılır. Benzer şekilde, @BeforeClass
ve @AfterClass
ek açıklamaları, JUnit4 tarafından bir test sınıfındaki tüm testleri yürütmeden önce kurulumu gerçekleştirmek ve sonrasında sökmek için yöntemlerde kullanılır. Sınıf kapsamı kurulumu ve sökme yöntemlerinin statik olması gerektiğini unutmayın. Test yöntemlerine gelince, JUnit'in önceki sürümünden farklı olarak, artık yöntem adını test
ile başlatmaları gerekmiyor, bunun yerine her birinin @Test
ile açıklanması gerekiyor. Her zamanki gibi, test yöntemleri herkese açık olmalı, dönüş değeri bildirmemeli, parametre almamalı ve istisnalar atabilir.
Enstrümantasyon sınıfı erişimi
Temel merhaba dünya örneğinde ele alınmasa da, bir Android testinin Instrumentation
örneğine erişim gerektirmesi oldukça yaygındır: bu, uygulama bağlamlarına, etkinlik yaşam döngüsüyle ilgili test API'lerine ve daha fazlasına erişim sağlayan temel API arayüzüdür.
JUnit4 testleri artık ortak bir temel sınıf gerektirmediğinden, Instrumentation
örneğini InstrumentationTestCase#getInstrumentation()
aracılığıyla elde etmek artık gerekli değildir; bunun yerine, yeni test çalıştırıcısı bunu, enstrümantasyon çerçevesi tarafından oluşturulan bağlamsal ve çevresel kurulumun depolandığı InstrumentationRegistry
aracılığıyla yönetir.
Instrumentation
sınıfının örneğine erişmek için InstrumentationRegistry
sınıfında getInstrumentation()
statik yöntemini çağırmanız yeterlidir:
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
Yerel olarak derleyin ve test edin
En yaygın kullanım durumları için Atest'i kullanın.
Daha yoğun özelleştirme gerektiren daha karmaşık durumlar için enstrümantasyon talimatlarını izleyin.