Bir Uygulama Örneği Hedefleme

Bu enstrümantasyon testi kategorisi, normal Android uygulamalarını hedefleyenlerden çok farklı değildir. Enstrümantasyon içeren test uygulamasının, hedeflediği uygulama ile aynı sertifika ile imzalanması gerektiğini belirtmekte fayda var.

Bu kılavuzun, platform kaynak ağacı iş akışı hakkında zaten biraz bilgi sahibi olduğunuzu varsaydığını unutmayın. Değilse, lütfen https://source.android.com/source/requirements adresine bakın. Burada ele alınan örnek, kendi test uygulama paketinde ayarlanan hedef paket ile yeni bir enstrümantasyon testi yazmaktır. Konsepte aşina değilseniz, lütfen Platform testi girişini okuyun.

Bu kılavuz, örnek teşkil etmesi için takip testini kullanır:

  • çerçeveler/taban/paketler/Kabuk/testler

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

Bir kaynak konumuna karar verme

Enstrümantasyon testi bir uygulamayı hedef alacağından, kural, test kaynak kodunu platform kaynak ağacında bileşen kaynak dizininizin kökü altındaki bir tests dizinine yerleştirmektir.

Kendi kendine enstrümantasyon testleri için uçtan uca örnekte kaynak konumu hakkında daha fazla tartışmaya bakın.

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ırsanız ve test tmodü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.

Örnek gerrit değişikliği için bildirim dosyasının en son sürümüne şu adresten erişilebilir: https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml

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="com.android.shell.tests">

    <application>
        <uses-library android:name="android.test.runner" />

        <activity
            android:name="com.android.shell.ActionSendMultipleConsumerActivity"
            android:label="ActionSendMultipleConsumer"
            android:theme="@android:style/Theme.NoDisplay"
            android:noHistory="true"
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.shell"
        android:label="Tests for Shell" />

</manifest>

Manifest dosyasındaki bazı seçkin açıklamalar:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

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.

Bu bir test uygulama paketi olduğundan, test edilen uygulama paketinden bağımsız olarak farklı bir paket adı kullanılmalıdır: yaygın bir kural .test soneki eklemektir.

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.

<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="com.android.shell"

Bu, enstrümantasyonun hedef paketini com.android.shell olarak ayarlar. Enstrümantasyon am instrument komutu aracılığıyla çağrıldığında, çerçeve com.android.shell işlemini yeniden başlatır ve testin yürütülmesi için işleme enstrümantasyon kodunu enjekte eder. Bu ayrıca, test kodunun, test edilen uygulamada çalışan tüm sınıf örneklerine erişimi olacağı ve açıkta kalan test kancalarına bağlı olarak durumu değiştirebileceği anlamına gelir.

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 Basit Test Yapılandırmasına bakın.

Karmaşık yapılandırma dosyası

Daha karmaşık testler 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.

Örnek gerrit değişikliği için yapılandırma dosyasının en son sürümüne şu adresten erişilebilir: frameworks/base/packages/Shell/tests/AndroidTest.xml

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

<configuration description="Runs Tests for Shell.">
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="ShellTests.apk" />
    </target_preparer>

    <option name="test-suite-tag" value="apct" />
    <option name="test-tag" value="ShellTests" />
    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.shell.tests" />
        <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="ShellTests.apk"/>
</target_preparer>

Bu, Trade Federation'a ShellTests.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="com.android.shell.tests"/>
  <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.

Test Modülü Yapılandırmaları hakkında daha fazla bilgi için buraya bakın

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.

Örnek gerrit değişikliği için en son kaynak koduna şu adresten erişilebilir: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

Test kalıpları genellikle bileşen ekiplerine özel olsa da, genel olarak faydalı bazı kullanım kalıpları vardır.

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

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 Android JUnit4 testi olarak çalıştırılması gerektiğini söylüyoruz.

@SmallTest ek açıklaması, tüm test sınıfı için bir test boyutu belirledi: bu test sınıfına eklenen tüm test yöntemleri, bu test boyutu açıklamasını devralır. ön test sınıfı kurulumu, test sonrası parçalama ve test sonrası sınıf parçalama: tearDown setUp ve yırtma yöntemlerine benzer. Test açıklaması, gerçek teste açıklama eklemek için kullanılır.

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

@Before notu, ön test kurulumunu gerçekleştirmek için JUnit4 tarafından yöntemlerde kullanılır. Bu örnekte kullanılmamasına rağmen, test sonrası sökme için @After da vardı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ılabilir. 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.

        Context context = InstrumentationRegistry.getTargetContext();

JUnit4 testleri artık ortak bir temel sınıf gerektirmediğinden, temel sınıf yöntemleri aracılığıyla getContext() veya getTargetContext() aracılığıyla Context örneklerinin elde edilmesi artık gerekli değildir; bunun yerine, yeni test çalıştırıcı bunları, enstrümantasyon çerçevesi tarafından oluşturulan bağlamsal ve çevresel kurulumun depolandığı InstrumentationRegistry aracılığıyla yönetir. Bu sınıf aracılığıyla şunları da arayabilirsiniz:

  • getInstrumentation() : Instrumentation sınıfının örneği
  • getArguments() : am instrument -e <key> <value> aracılığıyla iletilen komut satırı argümanları

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.