Test eşleme

Bu makalede, test eşlemeye dair kısa bir giriş ve Android Open Source Project'te (AOSP) testleri yapılandırmaya nasıl başlayacağınıza dair bir açıklama yer almaktadır.

Test eşleme hakkında

Test eşleme, geliştiricilerin doğrudan Android kaynak ağacında göndermeden önce ve gönderdikten sonra test kuralları oluşturmasına ve test edilecek şube ve cihazlarla ilgili kararları test altyapısına bırakmasına olanak tanıyan Gerrit tabanlı bir yaklaşımdır. Test eşleme tanımları, herhangi bir kaynak dizine yerleştirebileceğiniz TEST_MAPPING adlı JSON dosyalarıdır.

Atest, ilişkili dizinlerde göndermeden önce testleri çalıştırmak için TEST_MAPPING dosyalarını kullanabilir. Test eşleştirme sayesinde, Android kaynak ağacında minimum düzeyde değişiklik yaparak aynı test grubunu göndermeden önce yapılan kontrollere ekleyebilirsiniz.

Aşağıdaki örneklere bakın:

Test eşleme, test yürütme ve sonuç raporlama için Trade Federation (TF) test donanımından yararlanır.

Test gruplarını tanımlama

Test eşleme gruplarını test grubuyla test edin. Test grubunun adı herhangi bir dize olabilir. Örneğin, ön gönderme, değişiklikler doğrulanırken çalıştırılacak bir test grubunun adı olabilir. Gönderimden sonra, değişiklikler birleştirildikten sonra derlemeleri doğrulamak için kullanılan testler olabilir.

Paket oluşturma komut dosyası kuralları

Trade Federation test donanımının belirli bir derleme için test modüllerini çalıştırabilmesi için bu modüllerde Soong için bir test_suites veya Make için bu iki paketten birine ait bir LOCAL_COMPATIBILITY_SUITE ayarının olması gerekir:

  • general-tests, cihaza özgü özelliklere (ör. çoğu cihazda bulunmayan tedarikçiye özgü donanım) bağlı olmayan testler içindir. Bir ABI'ye, bit sayısına veya HWASan gibi donanım özelliklerine özel olsalar bile (her ABI için ayrı bir test_suites hedefi vardır) ve bir cihazda çalıştırılmaları gerekse bile çoğu test general-tests paketinde olmalıdır.
  • device-tests, cihaza özgü özelliklere bağlı testler içindir. Bu testler genellikle vendor/ altında bulunur. Cihaza özel, yalnızca bir cihaza özgü olan özellikleri ifade eder. Bu nedenle, JUnit testlerinin yanı sıra GTest testleri (ABI'ye özel olsalar bile genellikle general-tests olarak işaretlenmelidir) için de geçerlidir.

Örnekler:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

Testleri bir test paketinde çalışacak şekilde yapılandırma

Bir testin test paketinde çalışabilmesi için:

  • Derleme sağlayıcısı olmamalıdır.
  • Bittikten sonra temizlenmelidir. Örneğin, test sırasında oluşturulan geçici dosyaları silerek.
  • Sistem ayarları varsayılan veya orijinal değere değiştirilmelidir.
  • Cihazın belirli bir durumda (ör. root hazır) olduğunu varsaymaması gerekir. Çoğu testin çalıştırılması için root ayrıcalığı gerekmez. Bir testin root gerektirmesi gerekiyorsa bunu AndroidTest.xml içinde RootTargetPreparer ile belirtmelidir. Aşağıdaki örnekte gösterildiği gibi:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

Test eşleme dosyaları oluşturma

Test kapsamı gerektiren dizin için örneğe benzeyen bir TEST_MAPPING JSON dosyası ekleyin. Bu kurallar, söz konusu dizinde veya alt dizinlerinden herhangi birinde herhangi bir dosyaya dokunulduğunda testlerin göndermeden önce yapılan kontrollerde çalıştırılmasını sağlar.

Örneği takip edin

Aşağıda bir örnek TEST_MAPPING dosyası verilmiştir (JSON biçimindedir ancak yorumlar desteklenir):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Özellikleri ayarlama

Örnekte presubmit ve postsubmit, her test grubunun adıdır. Test grupları hakkında daha fazla bilgi için Test gruplarını tanımlama başlıklı makaleyi inceleyin.

Test modülünün adını veya Trade Federation entegrasyon testi adını (test XML dosyasının kaynak yolu, örneğin uiautomator/uiautomator-demo) name özelliğinin değerine ayarlayabilirsiniz. name alanının name sınıfını veya name test yöntemini kullanamayacağını unutmayın. Çalıştırılacağı testleri daraltmak için include-filter gibi seçenekleri kullanın. include-filter örnek kullanımına bakın.

Bir testin host ayarı, testin ana makinede çalışan cihazsız bir test olup olmadığını belirtir. Varsayılan değer false'tür. Bu, testin çalıştırılması için bir cihaz gerektiği anlamına gelir. Desteklenen test türleri GTest ikili dosyaları için HostGTest ve JUnit testleri için HostTest'tir.

file_patterns özelliği, herhangi bir kaynak kod dosyasının göreli yolunu (TEST_MAPPING dosyasını içeren dizine göre) eşleştirmek için normal ifade dizelerinin bir listesini ayarlamanıza olanak tanır. Örnek'te, CtsWindowManagerDeviceTestCases testi yalnızca TEST_MAPPING dosyasıyla veya alt dizinlerinden biriyle aynı dizinde bulunan ve Window veya Activity ile başlayan bir Java dosyası olduğunda göndermeden önce çalıştırılır. JSON dosyasında oldukları için ters eğik çizgilerin (\) kaçırılması gerekir.

imports özelliği, içeriği kopyalamadan testleri diğer TEST_MAPPING dosyalarına eklemenize olanak tanır. İçe aktarılan yolun üst dizinlerindeki TEST_MAPPING dosyaları da dahildir. Test eşleştirme, iç içe içe aktarıma olanak tanır. Yani iki TEST_MAPPING dosyası birbirini içe aktarabilir ve test eşleştirme, dahil edilen testleri birleştirebilir.

options özelliği, ek Tradefed komut satırı seçenekleri içerir.

Belirli bir test için kullanılabilen seçeneklerin tam listesini almak üzere şu komutu çalıştırın:

tradefed.sh run commandAndExit [test_module] --help

Seçeneklerin işleyiş şekli hakkında daha fazla bilgi için Tradefed'de seçeneklerin işlenmesi başlıklı makaleyi inceleyin.

Atest ile test yapma

Göndermeden önce test kurallarını yerel olarak çalıştırmak için:

  1. TEST_MAPPING dosyasını içeren dizine gidin.
  2. Aşağıdaki komutu çalıştırın:

    atest
    

Mevcut dizinin ve üst dizinlerinin TEST_MAPPING dosyalarında yapılandırılan tüm göndermeden önce testleri çalıştırılır. Atest, göndermeden önce iki test (A ve B) bulup çalıştırır.

Bu, geçerli çalışma dizinindeki (CWD) ve üst dizinlerdeki TEST_MAPPINGdosyalarda göndermeden önce test çalıştırmanın en basit yoludur. Atest, CWD'de ve tüm üst dizinlerinde TEST_MAPPING dosyasını bulup kullanır.

Yapının kaynak kodu

Bu örnekte, kaynak ağacında TEST_MAPPING dosyalarını nasıl yapılandırabileceğiniz gösterilmektedir:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

src/TEST_MAPPING içeriği:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

src/project_1/TEST_MAPPING içeriği:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

src/project_2/TEST_MAPPING içeriği:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

Hedef dizinleri belirtin

Belirli bir dizindeki TEST_MAPPING dosyalarında test çalıştırmak için hedef bir dizin belirtebilirsiniz. Aşağıdaki komut iki test (A, B) çalıştırır:

atest --test-mapping src/project_1

Gönderim sonrası test kurallarını çalıştırma

TEST_MAPPING'te tanımlanan gönderim sonrası test kurallarını src_path (varsayılan olarak CWD) ve üst dizinlerinde çalıştırmak için de bu komutu kullanabilirsiniz:

atest [--test-mapping] [src_path]:postsubmit

Yalnızca cihaz gerektirmeyen testleri çalıştırma

Yalnızca ana makineye göre yapılandırılmış ve cihaz gerektirmeyen testleri çalıştırmak için Atest için --host seçeneğini kullanabilirsiniz. Bu seçenek olmadan Atest hem cihaz gerektiren hem de cihaz gerektirmeyen bir ana makinede çalışan testleri çalıştırır. Testler iki ayrı pakette çalıştırılır:

atest [--test-mapping] --host

Test gruplarını tanımlama

Atest komutunda test gruplarını belirtebilirsiniz. Aşağıdaki komut, yalnızca bir test (C) içeren src/project_1 dizinindeki dosyalarla ilgili tüm postsubmit testlerini çalıştırır.

Dilerseniz gruptan bağımsız olarak tüm testleri çalıştırmak için :all simgesini de kullanabilirsiniz. Aşağıdaki komut dört test (A, B, C, X) çalıştırır:

atest --test-mapping src/project_1:all

Alt dizinleri dahil edin

Varsayılan olarak, Atest ile TEST_MAPPING'te test çalıştırıldığında yalnızca CWD (veya belirli dizin) ve üst dizinlerindeki TEST_MAPPING dosyasında yapılandırılan göndermeden önce testleri çalıştırılır. Alt dizinlerdeki tüm TEST_MAPPING dosyalarında test çalıştırmak isterseniz Atest'in bu testleri de dahil etmesini zorunlu kılmak için --include-subdir seçeneğini kullanın.

atest --include-subdir

--include-subdir seçeneği olmadan Atest yalnızca A testini çalıştırır. --include-subdir seçeneğiyle Atest iki test (A, B) çalıştırır.

Satır düzeyinde yorum desteklenir.

TEST_MAPPING dosyasını, aşağıdaki ayarın açıklamasıyla desteklemek için satır düzeyinde bir // biçimlendirme yorumu ekleyebilirsiniz. ATest ve Trade Federation, TEST_MAPPING öğesini yorum içermeyen geçerli bir JSON biçiminde ön işleme alır. JSON dosyasının temiz kalması için yalnızca satır düzeyinde // biçim yorumu desteklenir.

Örnek:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}