A Gradle plugin to ease testing in Kotlin Multiplatform projects.

Overview

Multiplatform Testing Plugin

A Gradle plugin for easy testing of Kotlin Multiplatform projects in your CI pipeline.

  • Support for testing android() targets on the emulator or a connected device. The plugin takes care of downloading SDK components, identifying the correct platform and system image, spinning up a well configured emulator and run the tests.

  • Support for testing androidNative*() binaries on the emulator or a connected device. Just like JVM-based android targets, the plugin takes care of the emulator setup and ensures that the device will be able to run the target architecture.

Component Status
Android JVM tests (Linux, amd64) Build Status
Android JVM tests (macOS, x64) Build Status
Android Native tests (Linux, amd64) Build Status
Android Native tests (macOS, x64) Build Status

To run the plugin, Gradle 6.8+ is required.

Install

The plugin is available on Maven Central. This means you have to add it to the project classpath:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("io.deepmedia.tools.testing:plugin:0.4.0")
    }
}

and then apply it to the desired project:

plugins {
    id("kotlin-multiplatform")
    id("io.deepmedia.tools.multiplatform-testing")
}

We also publish development snapshots with version latest-SNAPSHOT in sonatype:

buildscript {
    repositories {
        maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
    }
    dependencies {
        classpath("io.deepmedia.tools.testing:plugin:latest-SNAPSHOT")
    }
}

Android (JVM) targets

Requirements

A few things are required to test Android targets:

  1. A X64 host machine. The plugin might work properly on ARM, but this has not been tested yet. If it works (emulator runs), it is unlikely that X86-based binaries can be executed successfully.

  2. The Android SDK Command Line tools should be installed or, if they are not, you should provide a valid sdkHome directory in which they will be downloaded (macOS / Linux only).

    multiplatformTesting {
        androidTools {
            // path to installed SDK, or path where SDK will be installed
            // defaults to $ANDROID_HOME environment variable.
            sdkHome.set("path/to/sdk")
        }
    }
  3. Hardware acceleration. While Android documentation states that it is "recommended", hosts without acceleration are typically unable to run the emulator at all.

Tasks

Use ./gradlew tasks --group='Multiplatform Testing' to list all testing tasks.

The plugin provides two relevant tasks:

  • run Tests tasks: runs tests for the specified target, typically this will be runAndroidTests unless you used a custom name for the android target.
  • killAndroidEmulators task: kills all currently running emulators. Can be used to cleanup.

This means that the typical command will be:

./gradlew app:runAndroidTests app:killAndroidEmulators

Configuration

multiplatformTesting {
    android {
        // Enforce testing on a specific API level. If not set, we'll choose the API level in
        // a way that minimizes the number of emulators and the download of new system images.
        // Defaults to the MPT_ANDROID_API environment variable.
        apiLevel.set(21)

        // Enforce testing on a specific image tag. If not set, we'll choose the image tag in
        // a way that minimizes the number of emulators and the download of new system images.
        // Defaults to the MPT_ANDROID_TAG environment variable.
        tag.set("google_apis")

        // Choose the default variant that will be tested when running 'runAndroidTests'.
        // Defaults to the MPT_ANDROID_VARIANT environment variable, falls back to "debug".
        defaultVariant.set("debug")

        // By default, run* tasks execute both instrumented tests and unit tests.
        // Set this flag to false to avoid running unit tests.
        includeUnitTests.set(false)
    }
}

Android Native targets

Requirements

All the requirements for running Android JVM targets apply.

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.

  1. 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.
  2. 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.
  3. The plugin looks for a connected device (real device or emulator) that is able to run the architecture.
  4. If not found, the plugin looks for existing AVDs and starts the first one that would work.
  5. If not found, the plugin downloads the needed packages from sdkmanager, creates an AVD and starts it.
  6. 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.
  7. 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 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
You might also like...
Grazel is a Gradle plugin to automate generation of valid Bazel files for a given Android/Kotlin/Java project.

Grazel Grazel stands for Gradle to Bazel. It is a Gradle plugin that enables you to migrate Android projects to Bazel build system in an incremental a

Klinker is a gradle plugin making it possible to link kotlin native executables with custom linkers and options.

Klinker is a gradle plugin making it possible to link kotlin native executables with custom linkers and options. It does this by creating a static library for kotlin compilation, then generates a c+kotlin wrapper that calls into kotlin to start the app, finally using the specified compiler to compile and link the c code and kotlin library into a binary.

A Gradle plugin that improves the experience when developing Android apps, especially system tools, that use hidden APIs.

A Gradle plugin that improves the experience when developing Android apps, especially system tools, that use hidden APIs.

Gradle plugin which validates the licenses of your dependency graph match what you expect

Gradle plugin which validates the licenses of your dependency graph match what you expect

Artifactory is a gradle plugin to assist in developing Minecraft mods that can target different modloaders.

Artifactory Artifactory is a gradle plugin to assist in developing Minecraft mods that can target different modloaders. Currently, Fabric and Forge ar

Graphfity is a Gradle Plugin which creates a dependency node diagram graph about your internal modules dependencies, specially useful if you are developing a multi-module application
Graphfity is a Gradle Plugin which creates a dependency node diagram graph about your internal modules dependencies, specially useful if you are developing a multi-module application

Graphfity creates a dependency nodes diagram graph about your internal modules dependencies, specially useful if you are developing a multi-module app

A Gradle Plugin to determine which modules were affected by a set of files in a commit.
A Gradle Plugin to determine which modules were affected by a set of files in a commit.

A Gradle Plugin to determine which modules were affected by a set of files in a commit. One use case for this plugin is for developers who would like to only run tests in modules which have changed in a given commit.

EasyVersion is a Gradle plugin that manage your app or library version.

EasyVersion EasyVersion is a Gradle plugin that manage your app or library version. Before Downloading Create easy_version.json in your root project d

A Gradle plugin to help analyse the dependency between modules and run tasks only on modules impacted by specific set of changes.
A Gradle plugin to help analyse the dependency between modules and run tasks only on modules impacted by specific set of changes.

Change Tracker Plugin A Gradle plugin to help analyse the dependency between modules and run tasks only on modules impacted by specific set of changes

Comments
  • AVD .ini file not present if AVD was renamed

    AVD .ini file not present if AVD was renamed

    Need to search other ini files until the correct one is found, example:

    % cat /Users/Mattia/.android/avd/Pixel_3_API_32.ini avd.ini.encoding=UTF-8 path=/Users/Mattia/.android/avd/Pixel_5_API_32.avd path.rel=avd/Pixel_5_API_32.avd target=android-32

    opened by natario1 0
Releases(v0.4.0)
Owner
DeepMedia
A collection of mobile SDKs for augmented reality effects and media enhancement.
DeepMedia
A Gradle plugin that generates plugin.yml for Bukkit/BungeeCord/Nukkit plugins based on the Gradle project

plugin-yml is a simple Gradle plugin that generates the plugin.yml plugin description file for Bukkit plugins, bungee.yml for Bungee plugins or nukkit.yml for Nukkit plugins based on the Gradle project. Various properties are set automatically (e.g. project name, version or description) and additional properties can be added using a simple DSL.

Plexus 0 Apr 10, 2022
Gradle Plugin for Continuous Integration of AppSweep App Testing.

This Gradle plugin can be used to continuously integrate app scanning using AppSweep into your Android app build process

Guardsquare 28 Nov 13, 2022
Kmp4free - A Gradle Plugin that allows seamless switching between Kotlin JVM and the Kotlin Multiplatform Plugins

?? kmp4free Allows you to toggle between Kotlin JVM Plugin -> Kotlin Multiplatform with a Gradle Property kmp4free=true. This Gradle Plugin was built

Sam Edwards 61 Oct 14, 2022
Kotlin Gradle plugins for conveniently setting up Kotlin projects (JVM/MPP), publishing, Dokka, etc

Arrow Gradle config Add basic config to a Kotlin Multiplatform project In an Arrow KMP project, just add to the plugin block: plugins { kotlin("mu

ΛRROW 8 Aug 3, 2022
Gradle Plugin to automatically upgrade your gradle project dependencies and send a GitHub pull request with the changes

Gradle Plugin to automatically upgrade your gradle project dependencies and send a GitHub pull request with the changes

Dipien 142 Dec 29, 2022
Gradle plugin that generates a Swift Package Manager manifest and an XCFramework to distribute a Kotlin Multiplatform library for Apple platforms.

Multiplatform Swift Package This is a Gradle plugin for Kotlin Multiplatform projects that generates an XCFramework for your native Apple targets and

Georg Dresler 262 Jan 5, 2023
Gradle Plugin that determines if modules are Kotlin Multiplatform (KMP) ready.

Gradle Plugin that determines if modules are Kotlin Multiplatform (KMP) ready. KMP Ready means that the code is Kotlin Multiplatform compatible.

Sam Edwards 58 Dec 22, 2022
KMP Ready is a Gradle Plugin that provides actionable advice to make your code Kotlin Multiplatform compatible.

KMP Ready IS ?? UNDER DEVELOPMENT ?? Decisioning Logic Positive Signals ✅ Only Kotlin .kt Source Files Using Kotlin JVM Plugin Uses the Kotlin Multipl

Sam Edwards 58 Dec 22, 2022
Gradle Plugin that allows you to decompile bytecode compiled with Jetpack Compose Compiler Plugin into Java and check it

decomposer Gradle Plugin that allows you to decompile bytecode compiled with Jetpack Compose Compiler Plugin into Java and check it How to use Run bui

Takahiro Menju 56 Nov 18, 2022
Gradle Plugin to enable auto-completion and symbol resolution for all Kotlin/Native platforms.

CompleteKotlin Gradle Plugin to enable auto-completion and symbol resolution for all Kotlin/Native platforms. What this plugin provides This zero-conf

Louis CAD 235 Jan 3, 2023