Kendi Kendine Enstrüman Testleri Örneği

Bir enstrümantasyon testi başlatıldığında, hedef paketi enjekte edilen enstrümantasyon kodu ile yeniden başlatılır ve yürütme için başlatılır. Bir istisna, buradaki hedef paketin Android uygulama çerçevesinin kendisi, yani android paketi olamayacağıdır, çünkü bunu yapmak Android çerçevesinin yeniden başlatılmasının gerekeceği paradoksal bir duruma yol açar, bu da enstrümantasyon da dahil olmak üzere sistem işlevlerini destekler. 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 aracılığıyla açığa çıkanları çağırabilir. Bu test kategorisi için belirli bir paketi hedeflemek anlamlı değildir. Bu nedenle, bu tür enstrümantasyonların kendi AndroidManifest.xml <manifest> etiketinde tanımlandığı gibi kendi test uygulama paketini hedefleyecek şekilde beyan edilmesi alışılmış bir durumdur.

Gereksinimlere bağlı olarak, bu kategorideki test uygulama paketleri ayrıca:

  • Test için gerekli etkinlikleri toplayın.
  • Kullanıcı kimliğini sistemle paylaşın.
  • Platform anahtarı ile imzalanacak.
  • Genel SDK yerine çerçeve kaynağına göre derleyin.

Bu enstrümantasyon testleri kategorisine bazen kendi kendine enstrümantasyon denir. Platform kaynağındaki kendi kendine enstrümantasyon testlerine bazı örnekler:

Burada ele alınan örnek, kendi test uygulama paketinde ayarlanan hedef paketle yeni bir enstrümantasyon testi yazmaktır. Bu kılavuz, örnek olması için aşağıdaki testi kullanır:

Devam etmeden önce kabaca bir izlenim edinmek için önce koda göz atmanız önerilir.

Bir kaynak konumuna karar verme

Tipik olarak ekibiniz, kodu teslim etmek için yerleşik bir yer modeline ve testler eklenecek yerlere zaten sahip olacaktır. Çoğu ekip, tek bir git havuzuna sahiptir veya diğer ekiplerle bir depoyu paylaşır, ancak bileşen kaynak kodunu içeren özel bir alt dizine sahiptir.

Bileşen kaynağınız için kök konumunun <component source root> konumunda olduğunu varsayarsak, çoğu bileşenin altında src ve tests klasörleri ve Android.mk (veya ek .mk dosyalarına bölünmüş), AndroidManifest.xml bildirim dosyası gibi bazı ek dosyalar bulunur. AndroidManifest.xml ve test yapılandırma dosyası 'AndroidTest.xml'.

Yepyeni bir test eklediğinizden, muhtemelen src bileşeninizin yanında tests dizini oluşturmanız ve onu içerikle doldurmanız gerekecektir.

Bazı durumlarda, farklı test paketlerini ayrı apk'ler halinde paketleme ihtiyacı nedeniyle ekibiniz tests altında daha fazla dizin yapısına sahip olabilir. Ve 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 dolduracaksınız. Aşağıdaki bölümlerde her bir dosyanın ayrıntıları açıklanacaktır.

Manifest dosyası

Tıpkı normal bir uygulama gibi, her enstrümantasyon test modülünün bir bildirim dosyasına ihtiyacı vardır. Dosyayı AndroidManifest.xml olarak adlandırır ve test modülünüz için Android.mk yanında sağlarsanız, BUILD_PACKAGE çekirdek makefile tarafından otomatik olarak eklenir.

Daha fazla ilerlemeden önce, Uygulama Manifestosu Genel Bakışını incelemeniz önemle tavsiye edilir.

Bu, bir bildirim dosyasının temel bileşenlerine ve bunların işlevlerine genel bir bakış sağlar. platform_testing/tests/example/instrumentation/AndroidManifest.xml adresindeki örneğe bakın.

Kolaylık sağlamak için buraya bir anlık görüntü eklenmiştir:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

    <application/>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Manifest 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 paketi 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ıyla yalnızca bir uygulama yükleyebilir.

Ayrıca, bu package özniteliği, ComponentName#getPackageName() döndürdüğü öznitelik ile aynıdır ve ayrıca adb shell aracılığıyla çeşitli pm alt komutlarıyla etkileşimde bulunmak için kullandığınızla aynıdır.

Lütfen ayrıca, paket adının tipik olarak bir Java paket adıyla aynı stilde olmasına rağmen, aslında bununla ç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 bulundurabilir veya uygulama paket adıyla aynı test edebilirsiniz.

android:sharedUserId="android.uid.system"

Bu, kurulum sırasında bu apk'ye çekirdek platformla aynı kullanıcı kimliğinin, yani çalışma zamanı kimliğinin verilmesi gerektiğini beyan eder. Bunun, çekirdek platformla aynı sertifikayla imzalanan apk'ye bağlı olduğunu unutmayın (yukarıdaki bölümde LOCAL_CERTIFICATE bakın), ancak bunlar farklı kavramlardır:

  • bazı izinler veya API'ler, aynı imza sertifikasını gerektiren imza korumalıdır
  • bazı izinler veya API'ler, arayanın system kullanıcı kimliğini gerektirir; bu, çağıran paketin, çekirdek platformun kendisinden ayrı bir paketse system ile kullanıcı kimliğini paylaşmasını gerektirir.
<uses-library android:name="android.test.runner" />

İlgili sınıflar ayrı bir çerçeve jar kitaplığı dosyasında paketlendiğinden, bu nedenle test paketi uygulama çerçevesi tarafından çağrıldığında ek sınıf yolu girişleri gerektirdiğinden, bu tüm Enstrümantasyon testleri için gereklidir.

android:targetPackage="android.test.example.helloworld"

Buradaki targetPackage , bu dosyanın manifest etiketinde bildirilen package özniteliğiyle aynı şekilde bildirildiğini fark etmiş olabilirsiniz. Testin temelleri bölümünde bahsedildiği gibi, bu enstrümantasyon testi kategorisi tipik olarak çerçeve API'lerini test etmek için tasarlanmıştır, bu nedenle kendisinden başka belirli bir hedeflenen uygulama paketine sahip olmaları onlar için çok anlamlı değildir.

Basit yapılandırma dosyası

Her yeni test modülünün, yapı sistemini modül meta verileri, derleme zamanı bağımlılıkları ve paketleme yönergeleri ile yönlendirmek için bir yapılandırma dosyası olmalıdır. Çoğu durumda, Soong tabanlı Blueprint dosya 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 ayrıca Android'in test donanımı Trade Federation için bir test yapılandırma dosyası 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 konfigürasyon 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 Federasyonu'na HelloWorldTests.apk dosyasını belirtilen bir target_preparer kullanarak hedef cihaza yüklemesini söyler. Trade Federation'da geliştiricilerin kullanabileceği pek çok hedef hazırlayıcı vardır ve bunlar, test yürütmeden ö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ı belirtir ve yürütülecek cihazdaki pakete ve bu durumda JUnit olan test çalıştırma çerçevesine geçer.

Daha fazla bilgi için bkz. Test Modülü Yapılandırmaları .

JUnit4 özellikleri

android-support-test kitaplığının test yürütücüsü olarak kullanılması, yeni JUnit4 tarzı test sınıflarının benimsenmesini sağlar ve örnek gerrit değişikliği, özelliklerinin bazı çok temel kullanımları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 yararlı 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 miras alınması 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çıklama kullanırsınız. Bu örnekte, bu sınıfın bir JUnit4 testi olarak çalıştırılması talimatını veriyoruz.

    @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 ön test kurulumunu ve test sonrası ayırmayı gerçekleştirmek için 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 ardından sökmek için yöntemlerde kullanılır. Sınıf kapsamı kurulumu ve ayırma 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ı gerekmez, bunun yerine her birinin @Test ile açıklanması gerekir. Her zaman olduğu gibi, test yöntemleri genel olmalı, dönüş değeri bildirmemeli, parametre almamalı ve istisnalar atabilir.

Önemli : test yöntemlerinin kendilerine @Test ek açıklaması eklenmiştir; ve APCT aracılığıyla yürütülecek testlerin test boyutlarıyla açıklanması gerektiğini unutmayın: örnek açıklamalı yöntem testHelloWorld as @SmallTest . Ek açıklama, yöntem kapsamında veya sınıf kapsamında uygulanabilir.

instrumentation erişme

Temel merhaba dünya örneğinde ele alınmasa da, bir Android testi için 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() yoluyla 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.

InstrumentationRegistry sınıfı örneğine erişmek için, Instrumentation sınıfında getInstrumentation() statik yöntemini çağırmanız yeterlidir:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Yerel olarak oluşturun ve test edin

En yaygın kullanım durumları için Atest kullanın.

Daha fazla özelleştirme gerektiren daha karmaşık durumlar için enstrümantasyon talimatlarını izleyin.