简体   繁体   English

JUnit 5 用于 Android 测试

[英]JUnit 5 for Android testing

How to configure JUnit 5 for Android unit testing? Android单元测试如何配置JUnit 5? 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.

Refer to this issue and this issue regarding JUnit 5 support on Android.请参阅问题和有关 Android 上的 JUnit 5 支持的问题。

Add this build script dependency in your top-level build.gradle[.kts] file:在您的顶级build.gradle[.kts]文件中添加此构建脚本依赖项:

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

And add these lines in your app or library build.gradle[.kts] file:并将这些行添加到您的应用程序或库build.gradle[.kts]文件中:

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

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

You can use the above solution if you are using Android Gradle plugin 3.2.0 or higher and Gradle 4.7 or higher .如果您使用的是Android Gradle 插件 3.2.0 或更高版本Gradle 4.7 或更高版本,则可以使用上述解决方案。 For more information refer to the plugin GitHub page .有关更多信息,请参阅插件 GitHub 页面

Extended answer扩展答案

If you want to use JUnit 5 in your instrumented tests ( androidTest source set) do the following:如果您想在您的仪器测试( androidTest源集)中使用 JUnit 5,请执行以下操作:

  1. Add these dependencies to your app or libray build script:将这些依赖项添加到您的应用程序或 libray 构建脚本中:
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:在测试类中使用ActivityScenarioExtension而不是ActivityScenarioRule
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)
  }
}

Android Studio is based on IDEA, correct? Android Studio 是基于 IDEA 的,对吗?

Then see this answer here https://stackoverflow.com/a/46161799/1431016 or read directly the user-guide at http://junit.org/junit5/docs/current/user-guide/#running-tests-ide-intellij-idea然后在此处查看此答案https://stackoverflow.com/a/46161799/1431016或直接阅读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我还没有尝试过这个项目,但它可以帮助您在 Android 上使用 JUnit 5: https ://github.com/aurae/android-junit5

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首先去这里的 Junit官方文档https ://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api 你会看到像这样的所有最新版本在此处输入图像描述

then in your app/gradle add this dependencie :然后在你的 app/gradle 添加这个依赖:

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

where XXX is the version you want.其中 XXX 是您想要的版本。 For example in my case it was例如在我的情况下

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

You can use the official version by adding these lines to your gradle file:您可以通过将这些行添加到您的 gradle 文件来使用官方版本:

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:要继续与 Junit5 一起运行 JUnit4 测试,请添加:

testImplementation "org.junit.vintage:junit-vintage-engine:5.8.0"

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.现在是 2023 年 1 月,这里的答案曾经有效,但不适用于运行 Gradle 7.4 的 Android Studio 2021.3.1(补丁 1)。

This is what I did to make mine work:这就是我为使我的工作所做的:

  1. First, attempted to follow the answer by @Mahozad.首先,尝试遵循@Mahozad 的回答。 I chose it because it referred to the latest junit-jupiter:5.9.1 version .我选择它是因为它引用了最新的 junit-jupiter:5.9.1 版本
  2. But my app's build.gradle did not like the plugins {...} section from there, so I used apply plugin: 'de.mannodermaus.android-junit5' from @BoonKeatTeo's article .但是我的应用程序build.gradle不喜欢那里的plugins {...}部分,所以我使用了@BoonKeatTeo 文章中的apply plugin: 'de.mannodermaus.android-junit5'
  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)尽管如此,它还是无法识别任何导入的符号,因此我从@DagnogoJean-François 的回答中添加了存储库 URL (文件 > 设置 > 构建... > 远程 Jar 存储库)
  4. It continued complaining about an import static org.junit.jupiter.api.Assertions.*;它继续抱怨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.添加到测试 class 并从命令行gradlew build --warning-mode=all运行后,我意识到删除已弃用JCenter存储库是个好主意。
  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.我仍然有导入警告,所以我决定删除所有导入并接受 Android Studio 的建议以添加org.junit.jupiter:junit-jupiter:5.8.1依赖项。 This seems to have done the magic and now there are no warnings on any of my Test class symbols.这似乎已经产生了魔力,现在我的任何测试 class 符号上都没有警告。

To summarize, here is how my build.gradle looks now:总而言之,这是我的 build.gradle 现在的样子:

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.非常感谢关于如何进一步改进这一点的评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM