Jika Anda baru menggunakan Bazel, mulailah dengan tutorial Membangun Android dengan Bazel.

Gambar 1. Menjalankan pengujian instrumentasi Android paralel.
android_instrumentation_test
memungkinkan developer menguji aplikasi mereka di emulator dan perangkat Android.
Fitur ini menggunakan API framework Android yang sebenarnya dan Android Test Library.
Untuk hermetisitas dan kemampuan reproduksi, Bazel membuat dan meluncurkan emulator Android di sandbox, sehingga memastikan pengujian selalu berjalan dari status bersih. Setiap pengujian mendapatkan instance emulator terisolasi, sehingga pengujian dapat berjalan secara paralel tanpa meneruskan status di antara keduanya.
Untuk mengetahui informasi selengkapnya tentang pengujian instrumentasi Android, lihat dokumentasi developer Android.
Ajukan masalah di issue tracker GitHub.
Cara kerjanya
Saat Anda menjalankan bazel test pada target android_instrumentation_test untuk
pertama kalinya, Bazel akan melakukan langkah-langkah berikut:
- Membangun APK pengujian, APK yang sedang diuji, dan dependensi transitifnya
- Membuat, mem-boot, dan menyimpan status emulator bersih dalam cache
- Memulai emulator
- Menginstal APK
- Menjalankan pengujian menggunakan Android Test Orchestrator
- Menutup emulator
- Melaporkan hasilnya
Pada pengujian berikutnya, Bazel akan mem-boot emulator dari status bersih yang disimpan dalam cache yang dibuat pada langkah 2, sehingga tidak ada status sisa dari pengujian sebelumnya. Status emulator dalam cache juga mempercepat pengujian.
Prasyarat
Pastikan lingkungan Anda memenuhi prasyarat berikut:
Linux. Diuji di Ubuntu 16.04 dan 18.04.
Bazel 0.12.0 atau yang lebih baru. Verifikasi versi dengan menjalankan
bazel info release.
bazel info releaseHal ini akan menghasilkan output yang mirip dengan berikut ini:
release 4.1.0
- KVM. Bazel mengharuskan emulator memiliki akselerasi hardware dengan KVM di Linux. Anda dapat mengikuti petunjuk penginstalan ini untuk Ubuntu.
Untuk memverifikasi bahwa KVM memiliki konfigurasi yang benar, jalankan:
apt-get install cpu-checker && kvm-okJika pesan berikut dicetak, Anda memiliki konfigurasi yang benar:
INFO: /dev/kvm exists
KVM acceleration can be used
- Xvfb. Untuk menjalankan pengujian tanpa tampilan (misalnya, di server CI), Bazel memerlukan framebuffer virtual X.
Untuk menginstalnya, jalankan:
apt-get install xvfbVerifikasi bahwa Xvfb telah diinstal dengan benar dan diinstal di /usr/bin/Xvfb
dengan menjalankan:
which XvfbOutputnya adalah sebagai berikut:
/usr/bin/Xvfb
- Library 32-bit. Beberapa biner yang digunakan oleh infrastruktur pengujian adalah 32-bit, jadi di komputer 64-bit, pastikan biner 32-bit dapat dijalankan. Untuk Ubuntu, instal library 32-bit ini:
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386Memulai
Berikut adalah grafik dependensi target umum dari android_instrumentation_test:

Gambar 2. Grafik dependensi target dari an android_instrumentation_test.
File BUILD
Grafik ini diterjemahkan ke dalam file BUILD seperti ini:
android_instrumentation_test(
name = "my_test",
test_app = ":my_test_app",
target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86",
)
# Test app and library
android_binary(
name = "my_test_app",
instruments = ":my_app",
manifest = "AndroidTestManifest.xml",
deps = [":my_test_lib"],
# ...
)
android_library(
name = "my_test_lib",
srcs = glob(["javatest/**/*.java"]),
deps = [
":my_app_lib",
"@maven//:androidx_test_core",
"@maven//:androidx_test_runner",
"@maven//:androidx_test_espresso_espresso_core",
],
# ...
)
# Target app and library under test
android_binary(
name = "my_app",
manifest = "AndroidManifest.xml",
deps = [":my_app_lib"],
# ...
)
android_library(
name = "my_app_lib",
srcs = glob(["java/**/*.java"]),
deps = [
"@maven//:androidx_appcompat_appcompat",
"@maven//:androidx_annotation_annotation",
]
# ...
)
Atribut utama aturan android_instrumentation_test adalah:
test_app: Targetandroid_binary. Target ini berisi kode pengujian dan dependensi seperti Espresso dan UIAutomator. Targetandroid_binaryyang dipilih diperlukan untuk menentukan atributinstrumentsyang mengarah keandroid_binarylain, yang merupakan aplikasi yang sedang diuji.target_device: Targetandroid_device. Target ini menjelaskan spesifikasi emulator Android yang digunakan Bazel untuk membuat, meluncurkan, dan menjalankan pengujian. Lihat bagian tentang memilih perangkat Android untuk mengetahui informasi selengkapnya.
AndroidManifest.xml aplikasi pengujian harus menyertakan tag.<instrumentation>
Tag ini harus menentukan atribut untuk paket aplikasi target dan
nama class yang sepenuhnya memenuhi syarat dari runner pengujian instrumentasi,
androidx.test.runner.AndroidJUnitRunner.
Berikut adalah contoh AndroidTestManifest.xml untuk aplikasi pengujian:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.android.app.test"
android:versionCode="1"
android:versionName="1.0">
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.example.android.app" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="27" />
<application >
<!-- ... -->
</application>
</manifest>
Dependensi WORKSPACE
Untuk menggunakan aturan ini, project Anda harus bergantung pada repositori eksternal berikut:
@androidsdk: Android SDK. Download melalui Android Studio.@android_test_support: Menampung runner pengujian, peluncur emulator, danandroid_devicetarget. Anda dapat menemukan rilis terbaru di sini.
Aktifkan dependensi ini dengan menambahkan baris berikut ke WORKSPACE
file:
# Android SDK
android_sdk_repository(
name = "androidsdk",
path = "/path/to/sdk", # or set ANDROID_HOME
)
# Android Test Support
ATS_COMMIT = "$COMMIT_HASH"
http_archive(
name = "android_test_support",
strip_prefix = "android-test-%s" % ATS_COMMIT,
urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_COMMIT],
)
load("@android_test_support//:repo.bzl", "android_test_repositories")
android_test_repositories()
Dependensi Maven
Untuk mengelola dependensi pada artefak Maven dari repositori, seperti Google
Maven atau Maven Central,
Anda harus menggunakan resolver Maven, seperti
rules_jvm_external.
Bagian lain dari halaman ini menunjukkan cara menggunakan rules_jvm_external untuk
menyelesaikan dan mengambil dependensi dari repositori Maven.
Memilih target android_device
android_instrumentation_test.target_device menentukan perangkat Android mana yang akan
menjalankan pengujian. Target android_device ini ditentukan di
@android_test_support.
Misalnya, Anda dapat membuat kueri untuk sumber target tertentu dengan menjalankan:
bazel query --output=build @android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86Yang menghasilkan output yang terlihat mirip dengan:
# .../external/android_test_support/tools/android/emulated_devices/generic_phone/BUILD:43:1
android_device(
name = "android_23_x86",
visibility = ["//visibility:public"],
tags = ["requires-kvm"],
generator_name = "generic_phone",
generator_function = "make_device",
generator_location = "tools/android/emulated_devices/generic_phone/BUILD:43",
vertical_resolution = 800,
horizontal_resolution = 480,
ram = 2048,
screen_density = 240,
cache = 32,
vm_heap = 256,
system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_images",
default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_23_x86_props",
)
Nama target perangkat menggunakan template ini:
@android_test_support//tools/android/emulated_devices/device_type:system_api_level_x86_qemu2
Untuk meluncurkan android_device, system_image untuk level API yang dipilih diperlukan. Untuk mendownload image sistem, gunakan Android SDK's
tools/bin/sdkmanager. Misalnya, untuk mendownload image sistem untuk
generic_phone:android_23_x86, jalankan $sdk/tools/bin/sdkmanager
"system-images;android-23;default;x86".
Untuk melihat daftar lengkap target android_device yang didukung di
@android_test_support, jalankan perintah berikut:
bazel query 'filter("x86_qemu2$", kind(android_device, @android_test_support//tools/android/emulated_devices/...:*))'Bazel saat ini hanya mendukung emulator berbasis x86. Untuk performa yang lebih baik, gunakan
QEMU2 android_device target, bukan QEMU.
Menjalankan pengujian
Untuk menjalankan pengujian, tambahkan baris ini ke file project Anda
project root:/.bazelrc.
# Configurations for testing with Bazel
# Select a configuration by running
# `bazel test //my:target --config={headless, gui, local_device}`
# Headless instrumentation tests (No GUI)
test:headless --test_arg=--enable_display=false
# Graphical instrumentation tests. Ensure that $DISPLAY is set.
test:gui --test_env=DISPLAY
test:gui --test_arg=--enable_display=true
# Testing with a local emulator or device. Ensure that `adb devices` lists the
# device.
# Run tests serially.
test:local_device --test_strategy=exclusive
# Use the local device broker type, as opposed to WRAPPED_EMULATOR.
test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER
# Uncomment and set $device_id if there is more than one connected device.
# test:local_device --test_arg=--device_serial_number=$device_id
Kemudian, gunakan salah satu konfigurasi untuk menjalankan pengujian:
bazel test //my/test:target --config=guibazel test //my/test:target --config=headlessbazel test //my/test:target --config=local_device
Gunakan hanya satu konfigurasi atau pengujian akan gagal.
Pengujian tanpa tampilan
Dengan Xvfb, Anda dapat melakukan pengujian dengan emulator tanpa antarmuka grafis, yang juga dikenal sebagai pengujian tanpa tampilan. Untuk menonaktifkan antarmuka grafis
saat menjalankan pengujian, teruskan argumen pengujian --enable_display=false ke Bazel:
bazel test //my/test:target --test_arg=--enable_display=falsePengujian GUI
Jika variabel lingkungan $DISPLAY ditetapkan, Anda dapat mengaktifkan
antarmuka grafis emulator saat pengujian sedang berjalan. Untuk melakukannya, teruskan
argumen pengujian ini ke Bazel:
bazel test //my/test:target --test_arg=--enable_display=true --test_env=DISPLAYMenguji dengan emulator atau perangkat lokal
Bazel juga mendukung pengujian langsung pada emulator yang diluncurkan secara lokal atau perangkat terhubung. Teruskan tanda
--test_strategy=exclusive dan
--test_arg=--device_broker_type=LOCAL_ADB_SERVER untuk mengaktifkan mode pengujian lokal.
Jika ada lebih dari satu perangkat yang terhubung, teruskan tanda
--test_arg=--device_serial_number=$device_id dengan $device_id adalah ID
perangkat/emulator yang tercantum di adb devices.
Project contoh
Jika Anda mencari contoh project kanonis, lihat contoh pengujian Android untuk project yang menggunakan Espresso dan UIAutomator.
Penyiapan Espresso
Jika Anda menulis pengujian UI dengan Espresso
(androidx.test.espresso), Anda dapat menggunakan cuplikan berikut untuk menyiapkan ruang kerja Bazel dengan daftar artefak Espresso yang umum digunakan dan dependensinya:
androidx.test.espresso:espresso-core
androidx.test:rules
androidx.test:runner
javax.inject:javax.inject
org.hamcrest:java-hamcrest
junit:junit
Salah satu cara untuk mengatur dependensi ini adalah dengan membuat //:test_deps shared
library di file project root/BUILD.bazel Anda:
java_library(
name = "test_deps",
visibility = ["//visibility:public"],
exports = [
"@maven//:androidx_test_espresso_espresso_core",
"@maven//:androidx_test_rules",
"@maven//:androidx_test_runner",
"@maven//:javax_inject_javax_inject"
"@maven//:org_hamcrest_java_hamcrest",
"@maven//:junit_junit",
],
)
Kemudian, tambahkan dependensi yang diperlukan di project root/WORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "2.8"
RULES_JVM_EXTERNAL_SHA = "79c9850690d7614ecdb72d68394f994fef7534b292c4867ce5e7dec0aa7bdfad"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"junit:junit:4.12",
"javax.inject:javax.inject:1",
"org.hamcrest:java-hamcrest:2.0.0.0"
"androidx.test.espresso:espresso-core:3.1.1",
"androidx.test:rules:aar:1.1.1",
"androidx.test:runner:aar:1.1.1",
],
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
],
)
Terakhir, di target pengujian android_binary, tambahkan //:test_deps
dependensi:
android_binary(
name = "my_test_app",
instruments = "//path/to:app",
deps = [
"//:test_deps",
# ...
],
# ...
)
Tips
Membaca log pengujian
Gunakan --test_output=errors untuk mencetak log pengujian yang gagal, atau
--test_output=all untuk mencetak semua output pengujian. Jika Anda mencari log pengujian individual, buka
$PROJECT_ROOT/bazel-testlogs/path/to/InstrumentationTestTargetName.
Misalnya, log pengujian untuk BasicSample project kanonis ada di
bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest, jalankan:
tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTestHal ini akan menghasilkan output berikut:
$ tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest
.
├── adb.409923.log
├── broker_logs
│ ├── aapt_binary.10.ok.txt
│ ├── aapt_binary.11.ok.txt
│ ├── adb.12.ok.txt
│ ├── adb.13.ok.txt
│ ├── adb.14.ok.txt
│ ├── adb.15.fail.txt
│ ├── adb.16.ok.txt
│ ├── adb.17.fail.txt
│ ├── adb.18.ok.txt
│ ├── adb.19.fail.txt
│ ├── adb.20.ok.txt
│ ├── adb.21.ok.txt
│ ├── adb.22.ok.txt
│ ├── adb.23.ok.txt
│ ├── adb.24.fail.txt
│ ├── adb.25.ok.txt
│ ├── adb.26.fail.txt
│ ├── adb.27.ok.txt
│ ├── adb.28.fail.txt
│ ├── adb.29.ok.txt
│ ├── adb.2.ok.txt
│ ├── adb.30.ok.txt
│ ├── adb.3.ok.txt
│ ├── adb.4.ok.txt
│ ├── adb.5.ok.txt
│ ├── adb.6.ok.txt
│ ├── adb.7.ok.txt
│ ├── adb.8.ok.txt
│ ├── adb.9.ok.txt
│ ├── android_23_x86.1.ok.txt
│ └── exec-1
│ ├── adb-2.txt
│ ├── emulator-2.txt
│ └── mksdcard-1.txt
├── device_logcat
│ └── logcat1635880625641751077.txt
├── emulator_itCqtc.log
├── outputs.zip
├── pipe.log.txt
├── telnet_pipe.log.txt
└── tmpuRh4cy
├── watchdog.err
└── watchdog.out
4 directories, 41 files
Membaca log emulator
Log emulator untuk target android_device disimpan di /tmp/
direktori dengan nama emulator_xxxxx.log, dengan xxxxx adalah urutan karakter yang dibuat secara acak.
Gunakan perintah ini untuk menemukan log emulator terbaru:
ls -1t /tmp/emulator_*.log | head -n 1Menguji terhadap beberapa level API
Jika ingin menguji terhadap beberapa level API, Anda dapat menggunakan pemahaman daftar untuk membuat target pengujian untuk setiap level API. Contoh:
API_LEVELS = [
"19",
"20",
"21",
"22",
]
[android_instrumentation_test(
name = "my_test_%s" % API_LEVEL,
test_app = ":my_test_app",
target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_%s_x86_qemu2" % API_LEVEL,
) for API_LEVEL in API_LEVELS]
Masalah umum
- Proses server adb yang di-fork tidak dihentikan setelah pengujian
- Meskipun pembuatan APK berfungsi di semua platform (Linux, macOS, Windows), pengujian hanya berfungsi di Linux.
- Bahkan dengan
--config=local_adb, pengguna tetap harus menentukanandroid_instrumentation_test.target_device. - Jika menggunakan perangkat atau emulator lokal, Bazel tidak akan meng-uninstal APK setelah pengujian. Bersihkan paket dengan menjalankan perintah ini:
adb shell pm list
packages com.example.android.testing | cut -d ':' -f 2 | tr -d '\r' | xargs
-L1 -t adb uninstall