Nếu bạn mới sử dụng Bazel, hãy bắt đầu với bài viết Xây dựng Android bằng Hướng dẫn về Bazel.
Hình 1. Chạy chương trình kiểm thử đo lường song song trên Android.
android_instrumentation_test
cho phép nhà phát triển kiểm thử ứng dụng trên các trình mô phỏng và thiết bị Android.
Thư viện kiểm thử Android sử dụng API khung Android thực và Thư viện kiểm thử Android.
Nhằm đảm bảo tính ẩn giấu và khả năng tái tạo, Bazel tạo ra và ra mắt Android các trình mô phỏng trong một hộp cát, đảm bảo rằng các chương trình kiểm thử luôn chạy ở trạng thái sạch. Một kiểm thử sẽ nhận được một thực thể trình mô phỏng riêng biệt, cho phép các chương trình kiểm thử chạy song song mà không truyền trạng thái giữa chúng.
Để biết thêm thông tin về kiểm thử đo lường Android, hãy tham khảo nhà phát triển .
Vui lòng báo cáo vấn đề bằng công cụ theo dõi lỗi trong GitHub.
Cách hoạt động
Khi bạn chạy bazel test
trên mục tiêu android_instrumentation_test
cho giá trị
lần đầu tiên, Bazel thực hiện các bước sau:
- Tạo tệp APK kiểm thử, tệp APK đang kiểm thử cũng như các phần phụ thuộc bắc cầu của chúng
- Tạo, khởi động và lưu vào bộ nhớ đệm để xoá trạng thái của trình mô phỏng
- Khởi động trình mô phỏng
- Cài đặt APK
- Chạy kiểm thử bằng Android Test Orchestrator
- Tắt trình mô phỏng
- Báo cáo kết quả
Trong các lần chạy kiểm thử tiếp theo, Bazel khởi động trình mô phỏng từ trạng thái sạch và đã lưu vào bộ nhớ đệm được tạo ở bước 2 nên không có trạng thái còn lại nào trong các lần chạy trước. Lưu vào bộ nhớ đệm trạng thái trình mô phỏng cũng tăng tốc độ chạy kiểm thử.
Điều kiện tiên quyết
Đảm bảo môi trường của bạn đáp ứng các điều kiện tiên quyết sau:
Linux. Đã thử nghiệm trên Ubuntu 16.04 và 18.04.
Bazel 0.12.0 trở lên. Xác minh phiên bản bằng cách chạy
bazel info release
.
bazel info release
Kết quả trả về sẽ tương tự như kết quả sau:
release 4.1.0
- KVM. Bazel yêu cầu trình mô phỏng phải có phần cứng tăng tốc độ bằng KVM trên Linux. Bạn có thể làm theo các bước sau hướng dẫn cài đặt cho Ubuntu.
Để xác minh rằng KVM có cấu hình chính xác, hãy chạy mã:
apt-get install cpu-checker && kvm-ok
Nếu hệ thống in thông báo sau thì bạn đã có cấu hình chính xác:
INFO: /dev/kvm exists
KVM acceleration can be used
- Xvfb. Để chạy kiểm thử không có giao diện người dùng (ví dụ: trên máy chủ CI), Bazel yêu cầu bộ đệm khung ảo X.
Để cài đặt ứng dụng này, hãy chạy mã:
apt-get install xvfb
Xác minh rằng Xvfb
đã được cài đặt đúng cách và được cài đặt tại /usr/bin/Xvfb
bằng cách chạy:
which Xvfb
Kết quả sẽ như sau:
/usr/bin/Xvfb
- Thư viện 32 bit. Một số tệp nhị phân mà cơ sở hạ tầng kiểm thử sử dụng là 32 bit, vì vậy trên máy 64 bit, hãy đảm bảo rằng các tệp nhị phân 32 bit có thể chạy được. Để Ubuntu, cài đặt các thư viện 32 bit sau:
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386
Bắt đầu
Dưới đây là biểu đồ phần phụ thuộc mục tiêu điển hình của android_instrumentation_test
:
Hình 2. Biểu đồ phần phụ thuộc mục tiêu của android_instrumentation_test
.
XÂY DỰNG tệp
Biểu đồ này sẽ chuyển thành tệp BUILD
như sau:
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",
]
# ...
)
Các thuộc tính chính của quy tắc android_instrumentation_test
là:
test_app
: Mục tiêuandroid_binary
. Mục tiêu này chứa mã kiểm thử và như Espresso và UIAutomator.android_binary
đã chọn bắt buộc phải chỉ định một thuộc tínhinstruments
trỏ đến một thuộc tính khácandroid_binary
, đây là ứng dụng đang được kiểm thử.target_device
: Mục tiêuandroid_device
. Mục tiêu này mô tả các thông số kỹ thuật của trình mô phỏng Android mà Bazel sử dụng để tạo, khởi chạy và chạy các bài kiểm thử. Xem phần về cách chọn Android thiết bị để biết thêm thông tin.
AndroidManifest.xml
của ứng dụng kiểm thử phải bao gồm một <instrumentation>
.
Thẻ này phải chỉ định các thuộc tính cho gói của ứng dụng đích và
tên lớp đủ điều kiện của trình chạy kiểm thử đo lường,
androidx.test.runner.AndroidJUnitRunner
.
Dưới đây là ví dụ về AndroidTestManifest.xml
cho ứng dụng kiểm thử:
<?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>
Các phần phụ thuộc WORKSPACE
Để sử dụng quy tắc này, dự án của bạn cần phụ thuộc vào kho lưu trữ:
@androidsdk
: SDK Android. Hãy tải ứng dụng này xuống thông qua Android Studio.@android_test_support
: Lưu trữ trình chạy kiểm thử, trình chạy trình mô phỏng vàandroid_device
mục tiêu. Bạn có thể tìm thấy bản phát hành mới nhất tại đây.
Bật các phần phụ thuộc này bằng cách thêm các dòng sau vào WORKSPACE
tệp:
# 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()
Các phần phụ thuộc Maven
Để quản lý các phần phụ thuộc trên cấu phần phần mềm Maven qua các kho lưu trữ, chẳng hạn như Google
Maven hoặc Maven Central
bạn nên dùng trình phân giải Maven, chẳng hạn như
rules_jvm_external
.
Phần còn lại của trang này cho biết cách sử dụng rules_jvm_external
để
phân giải và tìm nạp các phần phụ thuộc qua kho lưu trữ Maven.
Chọn mục tiêu android_device
android_instrumentation_test.target_device
chỉ định thiết bị Android nào sẽ được kết nối
chạy bài kiểm thử. Các mục tiêu android_device
này được xác định trong
@android_test_support
.
Ví dụ: bạn có thể truy vấn các nguồn của một mục tiêu cụ thể bằng cách chạy:
bazel query --output=build @android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86
Kết quả nào sẽ cho ra kết quả tương tự như:
# .../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",
)
Tên mục tiêu thiết bị sử dụng mẫu sau:
@android_test_support//tools/android/emulated_devices/device_type:system_api_level_x86_qemu2
Để chạy android_device
, system_image
cho API đã chọn
là cấp độ bắt buộc. Để tải hình ảnh hệ thống xuống, hãy sử dụng
tools/bin/sdkmanager
. Ví dụ: để tải xuống hình ảnh hệ thống cho
generic_phone:android_23_x86
, chạy $sdk/tools/bin/sdkmanager
"system-images;android-23;default;x86"
.
Để xem danh sách đầy đủ các mục tiêu android_device
được hỗ trợ trong
@android_test_support
, hãy chạy lệnh sau:
bazel query 'filter("x86_qemu2$", kind(android_device, @android_test_support//tools/android/emulated_devices/...:*))'
Bazel hiện chỉ hỗ trợ các trình mô phỏng dựa trên x86. Để đạt được hiệu suất tốt hơn, hãy sử dụng
QEMU2
nhắm mục tiêu android_device
thay vì QEMU
mục tiêu.
Đang chạy kiểm thử
Để chạy kiểm thử, hãy thêm những dòng sau vào dự án của bạn
Tệp 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
Sau đó, hãy sử dụng một trong các cấu hình để chạy kiểm thử:
bazel test //my/test:target --config=gui
bazel test //my/test:target --config=headless
bazel test //my/test:target --config=local_device
Chỉ sử dụng một cấu hình, nếu không thử nghiệm sẽ không thành công.
Kiểm thử không có giao diện người dùng
Với Xvfb
, bạn có thể thử nghiệm bằng trình mô phỏng mà không cần
hay còn gọi là kiểm thử không có giao diện người dùng. Để tắt giao diện đồ hoạ
khi chạy kiểm thử, hãy truyền đối số kiểm thử --enable_display=false
cho Bazel:
bazel test //my/test:target --test_arg=--enable_display=false
Kiểm thử GUI (Giao diện người dùng đồ hoạ)
Nếu đã đặt biến môi trường $DISPLAY
, bạn có thể bật
giao diện đồ hoạ của trình mô phỏng trong khi chạy kiểm thử. Để thực hiện việc này, hãy chuyển
các đối số kiểm thử sau đây cho Bazel:
bazel test //my/test:target --test_arg=--enable_display=true --test_env=DISPLAY
Kiểm thử bằng trình mô phỏng hoặc thiết bị cục bộ
Bazel cũng hỗ trợ kiểm thử trực tiếp trên trình mô phỏng được khởi chạy cục bộ hoặc được kết nối
thiết bị. Truyền cờ
--test_strategy=exclusive
và
--test_arg=--device_broker_type=LOCAL_ADB_SERVER
để bật chế độ thử nghiệm cục bộ.
Nếu có nhiều thiết bị được kết nối, hãy chuyển cờ này
--test_arg=--device_serial_number=$device_id
, trong đó $device_id
là mã nhận dạng của
thiết bị/trình mô phỏng được liệt kê trong adb devices
.
Dự án mẫu
Nếu bạn đang tìm mẫu dự án chuẩn, hãy xem phần Kiểm thử Android mẫu cho các dự án sử dụng Espresso và UIAutomator.
Thiết lập Espresso
Nếu bạn viết quy trình kiểm thử giao diện người dùng bằng Espresso
(androidx.test.espresso
), bạn có thể sử dụng các đoạn mã sau để thiết lập
Không gian làm việc của Bazel với danh sách các cấu phần phần mềm Espresso thường dùng và
phần phụ thuộc:
androidx.test.espresso:espresso-core
androidx.test:rules
androidx.test:runner
javax.inject:javax.inject
org.hamcrest:java-hamcrest
junit:junit
Một cách để sắp xếp những phần phụ thuộc này là tạo một //:test_deps
dùng chung
trong tệp project root/BUILD.bazel
:
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",
],
)
Sau đó, hãy thêm các phần phụ thuộc bắt buộc trong 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",
],
)
Cuối cùng, trong mục tiêu android_binary
kiểm thử, hãy thêm //:test_deps
phần phụ thuộc:
android_binary(
name = "my_test_app",
instruments = "//path/to:app",
deps = [
"//:test_deps",
# ...
],
# ...
)
Mẹo
Đọc nhật ký kiểm thử
Sử dụng --test_output=errors
để in nhật ký cho các lượt kiểm thử không thành công, hoặc
--test_output=all
để in tất cả kết quả kiểm thử. Nếu bạn đang tìm kiếm một
nhật ký thử nghiệm cá nhân, truy cập vào
$PROJECT_ROOT/bazel-testlogs/path/to/InstrumentationTestTargetName
.
Ví dụ: nhật ký kiểm thử của dự án chính tắc BasicSample
đang ở
bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest
, chạy:
tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest
Kết quả như sau:
$ 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
Đọc nhật ký của trình mô phỏng
Nhật ký trình mô phỏng cho các mục tiêu android_device
được lưu trữ trong /tmp/
thư mục có tên emulator_xxxxx.log
, trong đó xxxxx
là một
chuỗi ký tự được tạo ngẫu nhiên.
Hãy dùng lệnh này để tìm nhật ký mới nhất của trình mô phỏng:
ls -1t /tmp/emulator_*.log | head -n 1
Kiểm thử theo nhiều cấp độ API
Nếu muốn kiểm thử ở nhiều cấp độ API, bạn có thể sử dụng danh sách mức độ hiểu bài khi tạo mục tiêu kiểm thử cho từng cấp độ API. Ví dụ:
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]
Vấn đề đã biết
- Các quy trình máy chủ adb đã phân nhánh không bị chấm dứt sau kiểm thử
- Mặc dù tính năng Xây dựng tệp APK hoạt động trên tất cả các nền tảng (Linux, macOS, Windows), nhưng hoạt động kiểm thử chỉ hoạt động trên Linux.
- Ngay cả với
--config=local_adb
, người dùng vẫn cần chỉ địnhandroid_instrumentation_test.target_device
. - Nếu bạn sử dụng một thiết bị hoặc trình mô phỏng cục bộ, Bazel sẽ không gỡ cài đặt các APK sau đó bài kiểm thử. Xoá gói bằng cách chạy lệnh sau:
adb shell pm list
packages com.example.android.testing | cut -d ':' -f 2 | tr -d '\r' | xargs
-L1 -t adb uninstall