Kendi kendini kaydeden testler örneği

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