Kendi Kendine Enstrüman Testleri Örneği

Bir enstrümantasyon testi başlatıldığında, enstrümantasyon kodu enjekte edilerek hedef paketi 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 olamamasıdır, çünkü böyle yapmak Android çerçevesinin yeniden başlatılmasının gerekeceği paradoksal bir duruma yol açacaktır; bu, enstrümantasyon dahil sistem işlevlerini destekleyen şeydir. kendisi.

Bu, bir enstrümantasyon testinin yürütülmek üzere 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 sunulanları çağırabilir. Bu test kategorisi için belirli bir paketi hedeflemek anlamlı değildir. Bu nedenle, bu tür enstrümantasyonların kendi <manifest> AndroidManifest.xml etiketinde tanımlandığı gibi kendi test uygulama paketini hedefleyecek şekilde bildirilmesi alışılmış bir durumdur.

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

  • Test için gerekli grup etkinlikleri.
  • Kullanıcı kimliğini sistemle paylaşın.
  • Platform anahtarıyla imzalayın.
  • Genel SDK yerine çerçeve kaynağına göre derlenir.

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

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

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

Bir kaynak konumuna karar verme

Tipik olarak ekibiniz, kodu kontrol etmek için yerleşik bir yer düzenine ve test eklemek için yerlere zaten sahip olacaktır. Çoğu takımın tek bir git deposu vardır veya birini 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 vardır ve Android.mk (veya ek .mk dosyalarına bölünmüş), manifest dosyası AndroidManifest.xml gibi bazı ek dosyalar vardır. AndroidManifest.xml ve 'AndroidTest.xml' test yapılandırma dosyası.

Yepyeni bir test eklediğiniz için, 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'lerde paketleme ihtiyacı nedeniyle ekibiniz tests altında başka dizin yapılarına sahip olabilir. Ve bu durumda, tests altında yeni bir alt dizin oluşturmanız gerekecek.

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 dosyanın daha ayrıntılı ayrıntıları açıklanacaktır.

bildirim dosyası

Normal bir uygulama gibi, her enstrümantasyon test modülünün bir manifest 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 dahil edilir.

Daha fazla ilerlemeden önce, öncelikle Uygulama Bildirimine Genel Bakış'ı gözden geçirmeniz önemle tavsiye edilir.

Bu, bir bildirim dosyasının temel bileşenlerine ve 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çkin açıklamalar:

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

package özelliğ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ı, o paket adıyla yalnızca bir uygulama kurabilir.

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

Paket adının genellikle 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 uygulamanızda en üst düzey Java paket adınızı veya testinizi uygulama paketi adıyla aynı tutabilirsiniz.

android:sharedUserId="android.uid.system"

Bu, kurulum zamanında, bu apk'ye çekirdek platformla aynı kullanıcı kimliğini, yani çalışma zamanı kimliğini 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 bölümüne bakın), ancak bunlar farklı kavramlardır:

  • bazı izinler veya API'ler, aynı imzalama sertifikasını gerektiren imza korumalıdır
  • bazı izinler veya API'ler, arayanın system kullanıcı kimliğini gerektirir; bu, çekirdek platformun kendisinden ayrı bir paketse, çağıran paketin 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, 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 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. Temel test bilgilerinde belirtildiği gibi, bu enstrümantasyon testi kategorisi tipik olarak çerçeve API'lerini test etmeye yöneliktir, bu nedenle kendileri dışında belirli bir hedeflenmiş 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 talimatlarıyla yönlendirmek için bir yapılandırma dosyası 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 Federation için de 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ı belirleyebilir. /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ına ilişkin bazı seçme açıklamalar:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>

Bu, Trade Federation'a HelloWorldTests.apk'yi belirtilen bir target_preparer kullanarak hedef cihaza yüklemesini söyler. Trade Federation'da geliştiricilerin kullanabileceği birçok 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 Trade Federation test sınıfını ve yürütülecek cihazdaki pakette ve bu durumda JUnit olan test çalıştırıcı çerçevesini belirtir.

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

JUnit4 özellikleri

android-support-test kitaplığını test çalıştırıcısı olarak kullanmak, 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 özel 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 miras alması gerekmemesidir; bunun yerine, testleri düz Java sınıflarında yazar ve belirli test kurulumlarını ve kısıtlamaları belirtmek için açıklama kullanırsınız. Bu örnekte, bu sınıfın bir JUnit4 testi olarak çalıştırılması gerektiğini söylü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ı, ön test kurulumunu ve test sonrası parçalamayı gerçekleştirmek için JUnit4 tarafından yöntemlerde kullanılır. Benzer şekilde, @BeforeClass ve @AfterClass ek açıklamaları, bir test sınıfındaki tüm testleri yürütmeden önce kurulumu gerçekleştirmek ve daha sonra sökmek için JUnit4 tarafından yöntemlerde kullanılır. Sınıf kapsamı kurulum 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ı gerekmez, bunun yerine her birine @Test ile açıklama eklenmelidir. Her zamanki gibi, test yöntemleri herkese açık olmalı, dönüş değeri bildirmemeli, parametre almamalı ve istisnalar atabilir.

Önemli : test yöntemlerinin kendilerine @Test notu eklenir; ve APCT aracılığıyla yürütülecek testler için test boyutlarıyla açıklamalı olmaları gerektiğini unutmayın: örnek açıklamalı yöntem testHelloWorld @SmallTest . Açıklama, yöntem kapsamında veya sınıf kapsamında uygulanabilir.

instrumentation erişim

Temel merhaba dünyası örneğinde kapsanmasa 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 arabirimidir.

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ı 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ının ö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 derleyin ve test edin

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

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