Bir enstrümantasyon testi başlatıldığında hedef paketi, enstrümantasyon kodu eklenmiş ve yürütme için başlatılmış olarak yeniden başlatılır. Buradaki hedef paket, Android uygulama çerçevesinin kendisi olamaz. Örneğin, android
paketi bu kapsamda değildir. Çünkü bu durumda, Android çerçevesinin yeniden başlatılması gerekir. Bu da, enstrümantasyonun kendisi de dahil olmak üzere sistem işlevlerini destekleyen bir işlemdir.
Bu, bir enstrümantasyon testinin yürütme için kendisini Android çerçevesine (diğer adıyla sistem sunucusu) yerleştiremeyeceği anlamına gelir. Android çerçevesini test etmek için test kodu yalnızca herkese açık 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 kategorisinde belirli bir paketi hedeflemek anlamlı değildir. Bu nedenle, bu tür enstrümanların kendi <manifest>
etiketinde AndroidManifest.xml
olarak tanımlandığı şekilde kendi test uygulama paketini hedefleyecek şekilde bildirilmesi yaygın bir uygulamadır.
Şartlara bağlı olarak, bu kategorideki test uygulama paketleri şunları da yapabilir:
- Test için gereken paket etkinlikleri.
- Kullanıcı kimliğini sistemle paylaşın.
- Platform anahtarıyla imzalanmalıdır.
- Herkese açık SDK yerine çerçeve kaynağına karşı derlenmelidir.
Bu enstrümantasyon testi kategorisine bazen kendi kendine enstrümantasyon adı verilir. Platform kaynağındaki kendi kendine enstrümantasyon testlerine ilişkin bazı örnekler aşağıda verilmiştir:
Burada ele alınan örnek, hedef paketin kendi test uygulaması paketine ayarlandığı yeni bir enstrümantasyon testi yazma işlemidir. Bu kılavuzda örnek olarak aşağıdaki test kullanılmaktadır:
Devam etmeden önce kabaca bir fikir edinmek için kodu incelemeniz önerilir.
Kaynak konumuna karar verme
Genellikle ekibiniz, kodda check-in yapılacak ve test eklenecek yerler konusunda önceden belirlenmiş bir düzene sahiptir. Çoğu ekip tek bir Git deposuna sahiptir veya diğer ekiplerle ortak bir Git deposu kullanı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>
olduğunu varsayarsak çoğu bileşenin altında src
ve tests
klasörleri bulunur. Ayrıca Android.mk
(veya ek .mk
dosyalarına ayrılmış), manifest dosyası AndroidManifest.xml
ve test yapılandırma dosyası "AndroidTest.xml" gibi bazı ek dosyalar da yer alır.
Yepyeni bir test eklediğiniz için büyük olasılıkla tests
dizinini bileşeninizin src
yanına oluşturmanız ve içeriğini doldurmanız gerekir.
Bazı durumlarda, farklı test paketlerinin ayrı APK'ler halinde paketlenmesi gerektiğinden ekibinizin tests
altında başka dizin yapıları olabilir. Bu durumda, tests
altında yeni bir alt dizin oluşturmanız gerekir.
Yapıdan bağımsız olarak, tests
dizinini veya yeni oluşturulan alt dizini, örnek Gerrit değişikliğindeki instrumentation
dizininde bulunanlara benzer dosyalarla doldurursunuz. Her dosyanın ayrıntıları bu belgenin ilerleyen kısımlarında açıklanmıştır.
Manifest dosyası
Uygulama projelerinde olduğu gibi, her enstrümantasyon testi modülü için AndroidManifest.xml
adlı bir manifest dosyası gerekir. BUILD_PACKAGE
çekirdek makefile'ı kullanarak bu dosyayı otomatik olarak eklemek için bu dosyayı test modülünüzün Android.mk
dosyasının yanına yerleştirin.
AndroidManifest.xml
dosyası hakkında bilginiz yoksa Uygulama Manifestine Genel Bakış başlıklı makaleyi inceleyin.
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>
Manifest dosyasıyla ilgili bazı önemli noktalar:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
package
özelliğ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ı, bu paket adına sahip yalnızca bir uygulama yükleyebilir.
Ayrıca bu package
özelliği, ComponentName#getPackageName()
tarafından döndürülenle aynıdır. Çeşitli pm
alt komutlarıyla etkileşim kurmak için de aynı özelliği kullanırsınız. adb shell
kullanın.
Paket adı genellikle Java paket adıyla aynı stilde olsa da aslında Java paket adıyla çok az ilgisi olduğunu unutmayın. Diğer bir deyişle, uygulama (veya test) paketiniz herhangi bir paket adıyla sınıflar içerebilir. Ancak basitliği tercih edebilir ve uygulamanızda veya testinizde üst düzey Java paket adınızın uygulama paket adıyla aynı olmasını sağlayabilirsiniz.
android:sharedUserId="android.uid.system"
Bu, yükleme sırasında bu APK dosyasına temel platformla aynı kullanıcı kimliğinin (yani çalışma zamanı kimliğinin) verilmesi gerektiğini belirtir. Bunun, APK'nın temel platformla aynı sertifikayla imzalanmasına bağlı olduğunu unutmayın (önceki bir bölümde LOCAL_CERTIFICATE
bölümüne bakın). Ancak bunlar farklı kavramlardır:
- Bazı izinler veya API'ler imza korumalıdır ve aynı imzalama sertifikası gerekir.
- Bazı izinler veya API'ler, arayanın
system
kullanıcı kimliğini gerektirir. Bu durumda, arayan paket, temel platformdan ayrı bir paketse kullanıcı kimliğinisystem
ile paylaşmalıdır.
<uses-library android:name="android.test.runner" />
İlgili sınıflar ayrı bir çerçeve JAR kitaplığı dosyasında paketlendiğinden bu, tüm enstrümantasyon testleri için gereklidir. Bu nedenle, test paketi uygulama çerçevesi tarafından çağrıldığında ek sınıf yolu girişleri gerekir.
android:targetPackage="android.test.example.helloworld"
Buradaki targetPackage
öğesinin, bu dosyanın manifest
etiketinde belirtilen package
özelliğiyle aynı şekilde tanımlandığını fark etmiş olabilirsiniz. Test temelleri bölümünde belirtildiği gibi, bu enstrümantasyon testi kategorisi genellikle çerçeve API'lerini test etmek için tasarlanmıştır. Bu nedenle, kendisi dışında belirli bir hedef uygulama paketine sahip olmaları çok anlamlı değildir.
Basit yapılandırma dosyası
Her yeni test modülünde, derleme sistemini modül meta verileri, derleme zamanı bağımlılıkları ve paketleme talimatlarıyla yönlendirmek için bir yapılandırma dosyası bulunmalıdır. Çoğu durumda, Soong tabanlı Blueprint dosyası seçeneği yeterlidir. Ayrıntılar için Basit Test Yapılandırması başlıklı makaleyi inceleyin.
Karmaşık yapılandırma dosyası
Bu daha karmaşık durumlarda, Android'in test koşum takımı Trade Federation için bir test yapılandırma dosyası da yazmanız gerekir.
Test yapılandırmasında, test sınıfına sağlanacak özel cihaz kurulumu seçenekleri ve varsayılan bağımsız değişkenler belirtilebilir. /platform_testing/tests/example/instrumentation/AndroidTest.xml adresindeki örneğe bakın.
Kolaylık sağlamak için buraya bir ekran görüntüsü 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ıyla ilgili bazı önemli noktalar:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
Bu komut, Trade Federation'a belirtilen bir target_preparer kullanarak HelloWorldTests.apk'yı hedef cihaza yüklemesini söyler. Ticaret Federasyonu'nda geliştiricilerin kullanımına sunulan birçok hedef hazırlayıcı vardır. Bunlar, test yürütülmeden önce cihazın düzgün şekilde kurulmasını sağlamak 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ı belirtir ve yürütülecek paketi cihazda ve test çalıştırıcı çerçevesini (bu durumda JUnit) geçirir.
Daha fazla bilgi için Test Modülü Yapılandırmaları başlıklı makaleyi inceleyin.
JUnit4 özellikleri
Test çalıştırıcı olarak android-support-test
kitaplığını kullanmak, yeni JUnit4 tarzı test sınıflarının benimsenmesini sağlar. Örnek Gerrit değişikliği, özelliklerinin çok temel bir 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 özgü olsa da genel olarak faydalı bazı kullanım kalıpları vardır.
@RunWith(JUnit4.class)
public class HelloWorldTest {
JUnit4'teki önemli bir fark, testlerin artık ortak bir temel test sınıfından devralınmasının gerekmemesidir. Bunun yerine, testleri düz Java sınıflarında yazıp belirli test kurulumunu ve kısıtlamaları belirtmek için ek açıklamayı kullanırsınız. Bu örnekte, bu sınıfın JUnit4 testi olarak çalıştırılması talimatı veriliyor.
@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
ek açıklamaları, JUnit4 tarafından yöntemlerde test öncesi kurulum ve test sonrası yıkım işlemlerini gerçekleştirmek için kullanılır. Benzer şekilde, @BeforeClass
ve @AfterClass
ek açıklamaları, bir test sınıfındaki tüm testler yürütülmeden önce kurulumu ve sonrasında yıkımı gerçekleştirmek için JUnit4 tarafından yöntemlerde kullanılır. Sınıf kapsamlı kurulum ve yıkım yöntemlerinin statik olması gerektiğini unutmayın. Test yöntemlerine gelince, JUnit'in önceki sürümlerinin aksine, yöntem adının test
ile başlaması gerekmez. Bunun yerine, her biri @Test
ile açıklama eklenmelidir. Her zamanki gibi, test yöntemleri herkese açık olmalı, dönüş değeri bildirmemeli, parametre almamalı ve istisnalar oluşturabilir.
Instrumentation 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 almak gerekmiyor. Bunun yerine, yeni test çalıştırıcı bunu InstrumentationRegistry
aracılığıyla yönetiyor. Burada, enstrümantasyon çerçevesi tarafından oluşturulan bağlamsal ve çevresel kurulum saklanıyor.
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 derleme ve test etme
En yaygın kullanım alanlarında Atest'i kullanın.
Daha fazla özelleştirme gerektiren daha karmaşık durumlarda enstrüman talimatlarını uygulayın.