Appium with Kotlin and JUnit 5
A working Kotlin/JUnit 5 test for an Android build on SpawnDroid, with UiAutomator2 options, AppiumBy selectors and teardown.
The Kotlin path uses the same Appium Java client and UiAutomator2 driver. The
test is idiomatic Kotlin: UiAutomator2Options, apply, and JUnit 5
lifecycle methods.
Gradle dependencies
Use the current Appium Java client and JUnit 5 from Maven Central:
dependencies {
testImplementation("io.appium:java-client:REPLACE_ME")
testImplementation("org.junit.jupiter:junit-jupiter:REPLACE_ME")
}
tasks.test {
useJUnitPlatform()
}The test
import io.appium.java_client.AppiumBy
import io.appium.java_client.android.AndroidDriver
import io.appium.java_client.android.options.UiAutomator2Options
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.net.URL
class CheckoutTest {
private lateinit var driver: AndroidDriver
@BeforeEach
fun setUp() {
val options = UiAutomator2Options().apply {
setPlatformName("Android")
setAutomationName("UiAutomator2")
setUdid(System.getenv("SPAWNDROID_UDID"))
setAppPackage(System.getenv("SPAWNDROID_APP_PACKAGE"))
setAutoGrantPermissions(true)
}
driver = AndroidDriver(
URL(System.getenv("SPAWNDROID_WD_URL")),
options,
)
}
@Test
fun addsItemToCart() {
driver.findElement(AppiumBy.accessibilityId("Add to cart")).click()
val total = driver.findElement(
AppiumBy.id("com.acme.checkout:id/total")
)
assertTrue(total.isDisplayed, "Cart total should be visible")
}
@AfterEach
fun tearDown() {
driver.quit()
}
}Do not set appium:app. The build is already installed on the session device.
Run it
export SPAWNDROID_WD_URL='https://stream.spawndroid.io/ci/sess_…/token/wd/hub'
export SPAWNDROID_UDID='emulator-5554'
export SPAWNDROID_APP_PACKAGE='com.acme.checkout'
./gradlew testGradle writes JUnit XML under build/test-results/test. Pass that path to the
GitHub Action's report-path input so failures show on the run page.
Kotlin-specific notes
UiAutomator2Optionsis a typed builder; prefer it to a rawDesiredCapabilitiesmap.AppiumBy.accessibilityIdmaps to a content description, not a resource id.- Use
@AfterEachrather than a JVM shutdown hook. The hook may run after the CI step has already timed out, leaving the device reserved. - If you assert inside a helper, let the exception propagate; JUnit records the failure and the teardown still runs.
In CI
- uses: kl3jvi/spawndroid/actions/android-test@v1
with:
api-key: ${{ secrets.SPAWNDROID_API_KEY }}
app-path: app/build/outputs/apk/debug/app-debug.apk
command: ./gradlew test
report-path: build/test-results/testRun it on SpawnDroid
Start free with 200 device-minutes a month, or read the capabilities guide.
Was this page helpful?
Appium with Java and TestNG
A working TestNG class for an Android build on SpawnDroid, including the Appium Java client setup, capabilities and teardown.
Appium with JavaScript and WebdriverIO
A working WebdriverIO setup for an Android build on SpawnDroid, with the config, capabilities, test and CI command.