Android Studio 3/Kotlin代码覆盖率

9

我的Android应用是多模块项目:

include (android-app/kotlin-android)':application', (pure kotlin)':presentation', (pure kotlin)':domain', (android-library/kotin-android)':dataproviders'

我正在使用 Junit/Mockito 进行测试,但是我在为 Kotlin Android 模块生成代码覆盖率时遇到了问题。只有 Android Studio 中可见的已测试行才能被显示出来。 code coverage report

在 ui.viewmodel 包中进行测试的类:

tested lines for kotlin-android module

但是,对于纯Kotlin(例如领域、表示层),测试覆盖率工作正常: code coverage report pure kotlin module 我正在使用Android Studio 3.0 Canary 8 你可以在我的github上查看我的build.gradle文件:

build.gradle

dependencies.gradle

application.build.gradle

presentation.build.gradle

在 Android 应用程序模块中的示例测试: MostPopularViewModelTest 在纯 Kotlin 模块中的示例测试: MostPopularPresenterTest 有人可以帮我解决问题吗?我尝试使用 Jacoco 生成代码覆盖率,但它也没有显示代码覆盖率。

2个回答

9
解决方案是在模块的build.gradle中添加以下Gradle任务:
task copyTestClasses(type: Copy) {
    from "build/tmp/kotlin-classes/debugUnitTest"
    into "build/intermediates/classes/debug"
}

并运行:

gradlew copyTestClasses

然后,无需问题地生成代码覆盖率报告。

3
这似乎是在报告测试结果而非代码覆盖率? - Elye
1
感谢这个技巧!@Elye是对的,你应该从“build/tmp/kotlin-classes/debug”复制。 - Rule
@Hype请查看待处理的编辑,并在您认为需要改进您的答案时批准它。 - Blue

1

虽然@Hype的解决方案有效,但它也会在环境中混淆一些东西,因为你最终会得到kotlin类文件和META-INF与来自Java的类文件在同一个目录中。这可能会导致第二次运行编译时出现一些问题。

另一个解决方案是只需将kotlin类的路径添加到jacoco配置参数classDirectories中。 这个解决方案只是告诉jacoco它需要评估来自两个不同文件树的文件。好处是它不会改变你的环境。 以下是如何组合来自多个目录的类文件的示例,排除任何不需要的文件(这取决于你的项目设置,你可能使用dagger并且必须排除dagger生成的文件):

def javaAndKotlinClassFiles = files(fileTree(dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
                                excludes: ['**/R.class',
                                           '**/R$*.class',
                                           '**/*$ViewInjector*.*',
                                           '**/*$ViewBinder*.*',
                                           '**/BuildConfig.*',
                                           '**/Manifest*.*',
                                           '**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
                                           '**/*_Provide*Factory*.*',
                                           '**/*$*$*.*', // Anonymous classes generated by kotlin
                                           '**/*Test*.*', // Test files
                                           '**/*Spec*.*' // Test files
                                ]
                                    ).files)
                    .from(files(fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/${sourcePath}",
                            excludes: ['**/R.class',
                                       '**/R$*.class',
                                       '**/*$ViewInjector*.*',
                                       '**/*$ViewBinder*.*',
                                       '**/BuildConfig.*',
                                       '**/Manifest*.*',
                                       '**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
                                       '**/*_Provide*Factory*.*',
                                       '**/*$*$*.*', // Anonymous classes generated by kotlin
                                       '**/*Test*.*', // Test files
                                       '**/*Spec*.*' // Test files
                                    ]).files)
                    )
            classDirectories = javaAndKotlinClassFiles

这里有一个不错的指南,教你如何为Java设置它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接