简体   繁体   English

Android Studio 3 / Kotlin代码覆盖率

[英]Android Studio 3/Kotlin code coverage

My android app is multi module project: 我的Android应用程序是多模块项目:

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

I'm using Junit/Mockito for tests and I have issue with generating code coverage for kotlin android modules only . 我正在使用Junit / Mockito进行测试,我遇到的问题只是为kotlin android模块生成代码覆盖率。 代码覆盖率报告 Tested lines are visible for android studio. Android studio可以看到经过测试的行。

tested class in ui.viewmodel package: ui.viewmodel包中的测试类:

测试了kotlin-android模块的行

But, for pure kotlin (eg. domain, presentation) test coverage works fine: 但是,对于纯kotlin (例如域,演示)测试覆盖率工作正常: 代码覆盖率报告纯kotlin模块

I'm using Android Studio 3.0 Canary 8 You can look at my build.gradle files at github: 我正在使用Android Studio 3.0 Canary 8您可以在github上查看我的build.gradle文件:

build.gradle 的build.gradle

dependencies.gradle dependencies.gradle

application.build.gradle application.build.gradle

presentation.build.gradle presentation.build.gradle

Example test in android application module: android应用程序模块中的示例测试:

MostPopularViewModelTest MostPopularViewModelTest

Example test in pure kotlin module: 纯kotlin模块中的示例测试:

MostPopularPresenterTest MostPopularPresenterTest

Can someone help me with my problem? 有人可以帮我解决我的问题吗? I tried generate code coverage via Jacoco but it also did not show code coverage. 我尝试通过Jacoco生成代码覆盖,但它也没有显示代码覆盖率。

Solution is to add this this gradle task in build.gradle for module: 解决方案是在build.gradle for module中添加此gradle任务:

task copyTestClasses(type: Copy) {
    from "build/tmp/kotlin-classes/debugUnitTest"
    into "build/intermediates/classes/debug"
}

And run: 并运行:

gradlew copyTestClasses

Then generate code coverage report without problems. 然后生成代码覆盖率报告没有问题。

Although the solution from @Hype works, it also messes a bit the environment as you end up with kotlin class files and META-INF in the same directory as the class files from java. 虽然来自@Hype的解决方案可行,但它也会让环境变得有些混乱,因为你最终将kotlin类文件和META-INF放在与java类文件相同的目录中。 This might give you some issues running the compilation for a second time. 这可能会让您在第二次运行编译时遇到一些问题。

Another solution would be to just add the path for kotlin classes to jacoco configuration parameter classDirectories . 另一个解决方案是将kotlin类的路径添加到jacoco配置参数classDirectories This solution would simply tell jacoco that it needs to evaluate files from two different file trees. 这个解决方案只是告诉jacoco它需要评估来自两个不同文件树的文件。 The upside is that it does not change your environment. 好处是它不会改变你的环境。 Here's a sample of how you could combine class files from multiple directories, excluding any unwanted files (this is depending on your project setup, you might use dagger and have to exclude dagger generated files): 下面是一个如何组合来自多个目录的类文件的示例,不包括任何不需要的文件(这取决于您的项目设置,您可能使用匕首并且必须排除匕首生成的文件):

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

Here's a nice guide for how to set it up for Java. 这是一个很好的指南 ,介绍如何为Java设置它。

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

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