Kendi kendine aletli testler örneği

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ğini system 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 ek 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ı ö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.