Android (native) targets
Requirements
All the requirements for running Android JVM targets apply.
In addition, it is highly recommended to use a X64 host machine, especially to be able to test all four architectures (x86, x86_64, armeabi-v7a, arm64-v8a). The plugin might work on ARM hosts but this has not been tested, and anyway ARM emulators would not be able to run non-ARM binaries, while x86-based hosts can run ARM code through binary translation.
How it works
Running Android Native tests is a multi-step process and between these steps, the plugin applies workarounds to known issues to make testing as smooth and fast as possible.
- A K/N test executable is built. These executables are built by the Kotlin compiler with the -tr option and automatically run all test suites and print logs to Android logcat.
- K/N test executables are currently broken.
The plugin workarounds this issue by treating them as shared libraries and loading them at
runtime using
dlopen()
and passing appropriate arguments to trick the Kotlin runtime launcher. - The plugin looks for a connected device (real device or emulator) that is able to run the architecture.
- If not found, the plugin looks for existing AVDs and starts the first one that would work.
- If not found, the plugin downloads the needed packages from
sdkmanager
, creates an AVD and starts it. - The runner executable is executed using
adb shell
. This makes a huge difference with respect to e.g. JNI-based tests, as we don't have to wait for the emulator to be completely booted and care about all details (unlock, avoid welcome screens, animations...) that make testing hard in a JVM process. - Interesting logcat logs are printed to the host stdout.
Tasks
Use
./gradlew tasks --group='Multiplatform Testing'
to list all testing tasks.
The plugin provides three types of tasks:
runAllAndroidNativeTests
task: runs tests for all androidNative* targets.run<TargetName>Tests
tasks: runs tests for the specified target, e.g.runAndroidNativeX86Tests
killAndroidEmulators
task: kills all currently running emulators. Can be used to cleanup.
Using the runAllAndroidNativeTests
tasks is recommended, because it ensures the most efficient
emulator installation. This is because emulator images can run multiple architectures
(for example: 64bit images might run 32bit binaries, and X86/64 images might run ARM binaries through binary
translation). The plugin is aware of this and, if runAllAndroidNativeTests
is used, is able to pick up the best
emulator for the job, saving time and resources.
This means that the typical command will be:
./gradlew app:runAllAndroidNativeTests app:killAndroidEmulators