JUnit 5 for Android testing
Asked Answered
W

6

31

How to configure JUnit 5 for Android unit testing? I tried:

testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0")

But it doesn't work, when I run previous the simplest unit test:

@Test
public void addition_isCorrect() throws Exception {
    assertEquals(4, 2 + 2);
}

I get error:

Exception in thread "main" java.lang.NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.getDefaultClassLoader()Ljava/lang/ClassLoader;
    at org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry.loadTestEngines(ServiceLoaderTestEngineRegistry.java:31)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:42)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:36)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1
Empty test suite.
Wampler answered 11/9, 2017 at 17:17 Comment(1)
Related post: How to use JUnit 5 with Gradle?Lurlenelurline
L
34

Refer to this issue and this issue regarding JUnit 5 support on Android.

Add this build script dependency in your top-level build.gradle[.kts] file:

buildscript {
  dependencies {
    classpath("de.mannodermaus.gradle.plugins:android-junit5:1.8.2.1")
  }
}

And add these lines in your app or library build.gradle[.kts] file:

plugins {
  // ...
  id("de.mannodermaus.android-junit5")
}

dependencies {
  // Aggregator dependency on JUnit api, engine, and params
  testImplementation("org.junit.jupiter:junit-jupiter:5.9.1")
  // (Optional) If you also have JUnit 4-based tests
  testImplementation("junit:junit:4.13.2")
  testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.9.1")
}

You can use the above solution if you are using Android Gradle plugin 3.2.0 or higher and Gradle 4.7 or higher. For more information refer to the plugin GitHub page.

Extended answer

If you want to use JUnit 5 in your instrumented tests (androidTest source set) do the following:

  1. Add these dependencies to your app or libray build script:
androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.3.0")
androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.3.0")
  1. Use ActivityScenarioExtension instead of ActivityScenarioRule in your test classes:
import de.mannodermaus.junit5.ActivityScenarioExtension

class MyActivityTest {

  @JvmField
  @RegisterExtension
  val scenarioExtension = ActivityScenarioExtension.launch<MyActivity>()

  @Test
  fun test1() {
    val scenario = scenarioExtension.scenario
    scenario.moveToState(Lifecycle.State.RESUMED)
    assertThat(scenario.state).isEqualTo(Lifecycle.State.RESUMED)
  }

  @Test
  fun test2(scenario: ActivityScenario<MyActivity>) {
    scenario.moveToState(Lifecycle.State.RESUMED)
    assertThat(scenario.state).isEqualTo(Lifecycle.State.RESUMED)
  }
}
Lurlenelurline answered 7/12, 2018 at 17:27 Comment(0)
W
4

Android Studio is based on IDEA, correct?

Then see this answer here https://mcmap.net/q/103643/-intellij-junit-5-jupiter or read directly the user-guide at http://junit.org/junit5/docs/current/user-guide/#running-tests-ide-intellij-idea

Summary:

// Only needed to run tests in an IntelliJ IDEA that bundles an older version
testImplementation("org.junit.platform:junit-platform-launcher:1.0.0")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.0.0")
testImplementation("org.junit.vintage:junit-vintage-engine:4.12.0")

I didn't try this project yet, but it could help you using JUnit 5 on Android: https://github.com/aurae/android-junit5

Washstand answered 11/9, 2017 at 18:9 Comment(0)
D
3

You can use the official version by adding these lines to your gradle file:

android {
    testOptions {
        unitTests.all {
            useJUnitPlatform()
    }
  }
}



dependencies {
     testImplementation "org.junit.jupiter:junit-jupiter:5.8.0"
}

To continue to run your JUnit4 tests alongside Junit5, add:

testImplementation "org.junit.vintage:junit-vintage-engine:5.8.0"
Diamonddiamondback answered 15/10, 2022 at 19:16 Comment(0)
M
3

It is January 2023 and the answers here that used to work, do not work for me on Android Studio 2021.3.1 (Patch 1), running Gradle 7.4.

This is what I did to make mine work:

  1. First, attempted to follow the answer by @Mahozad. I chose it because it referred to the latest junit-jupiter:5.9.1 version.
  2. But my app's build.gradle did not like the plugins {...} section from there, so I used apply plugin: 'de.mannodermaus.android-junit5' instead, from @BoonKeatTeo's article.
  3. Still, it would not recognize any of the imported symbols and so I added the repository URL from @DagnogoJean-François's answer (File > Settings > Build... > Remote Jar Repositories)
  4. It continued complaining about an import static org.junit.jupiter.api.Assertions.*; added to Test class and after running from the command line gradlew build --warning-mode=all, I realized that it is a good idea to remove the deprecated jcenter repository. In addition to removing it via Settings, I replaced all jcenter() occurrences with mavenCentral() in the root build.gradle.
  5. I still had the import warning, so I decided to remove all imports and accept the suggestion by Android Studio to add a org.junit.jupiter:junit-jupiter:5.8.1 dependency. This seems to have done the magic and now there are no warnings on any of my Test class symbols.

To summarize, here is how my build.gradle looks now:

apply plugin: 'com.android.library'
apply plugin: 'de.mannodermaus.android-junit5'

android {
    compileSdkVersion 33
    buildToolsVersion "33.0.1"
    compileOptions.encoding = 'windows-1251'
    useLibrary 'org.apache.http.legacy'
    namespace 'com.susu.mylib'

    defaultConfig {
        minSdkVersion 26
        targetSdkVersion 33
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles 'proguard.cfg'
        }
    }

    testOptions {
        unitTests.all {
            useJUnitPlatform()
        }
    }
}

dependencies {
    implementation "androidx.core:core-ktx:1.9.0"
    implementation 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
    implementation "com.android.billingclient:billing:5.1.0"

    implementation 'org.junit.jupiter:junit-jupiter:5.8.1'
}

Comments on how to improve this further are greatly appreciated.

Mantilla answered 8/1, 2023 at 14:5 Comment(0)
C
2

USE ALWAYS THE OFFICIAL VERSION

First go to the official documentation of Junit here : https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api you will see all latest version like this enter image description here

then in your app/gradle add this dependencie :

testImplementation('org.junit.jupiter:junit-jupiter:X.X.X')

where X.X.X is the version you want. For example in my case it was

testImplementation('org.junit.jupiter:junit-jupiter:5.6.0')

Coconut answered 3/2, 2020 at 13:56 Comment(1)
I agree with you but the official version doesn't work with instrumentation tests. If you add androidTestImplementation('org.junit.jupiter:junit-jupiter:X.X.X') you encounter by some errorsDesdee
G
0

Adding the android-junit5 plugin solves the problem

plugins {
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsKotlinAndroid)
    // use JUnit5 for tests
    id("de.mannodermaus.android-junit5") version "1.10.0.0"
}

android-junit5

Goddaughter answered 12/3 at 7:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.