kotlin verion: 1.3.61
安卓Gradle插件: 3.5.3
JaCoCo版本: 0.8.4.201905082037 (默认安卓级版本)
项目:https://github.com/goldy1992/Mp3Player/tree/feature/issue-112/migrate-to-kotlin
我有一个多模块级项目,有:2种口味:完全自动化2种构建类型:发布、调试
我正在把所有的东西都迁移到kotlin。
模块结构
对于这篇文章的上下文,我只对单元测试感兴趣
然而,由于一些(并非全部) kotlin编译类被确认为“工具化类”,所以测试按预期运行,因此不会产生覆盖范围。
出现这些错误时,许多类的测试即将打印如下内容:
java.lang.instrument.IllegalClassFormatException: Error while instrumenting com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder.
at org.jacoco.agent.rt.internal_035b120.CoverageTransformer.transform(CoverageTransformer.java:93)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at org.junit.runners.model.TestClass.getSortedDeclaredFields(TestClass.java:77)
at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.robolectric.internal.SandboxTestRunner.<init>(SandboxTestRunner.java:71)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:101)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:96)
at sun.reflect.GeneratedConstructorAccessor5.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder.buildRunner(DefensiveAllDefaultPossibilitiesBuilder.java:113)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder.runnerForClass(DefensiveAllDefaultPossibilitiesBuilder.java:56)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.vintage.engine.discovery.TestClassRequestResolver.createRunnerTestDescriptor(TestClassRequestResolver.java:55)
at org.junit.vintage.engine.discovery.VintageDiscoverer.lambda$discover$0(VintageDiscoverer.java:53)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.vintage.engine.discovery.VintageDiscoverer.discover(VintageDiscoverer.java:55)
at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:62)
at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:168)
at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:155)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
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 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
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 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Error while instrumenting com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder.
at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrumentError(Instrumenter.java:158)
at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:108)
at org.jacoco.agent.rt.internal_035b120.CoverageTransformer.transform(CoverageTransformer.java:91)
... 86 more
Caused by: java.lang.IllegalStateException: Cannot process instrumented class com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder. Please supply original non-instrumented classes.
at org.jacoco.agent.rt.internal_035b120.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:237)
at org.jacoco.agent.rt.internal_035b120.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:55)
at org.jacoco.agent.rt.internal_035b120.asm.ClassVisitor.visitField(ClassVisitor.java:287)
at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.readField(ClassReader.java:906)
at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.accept(ClassReader.java:683)
at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.accept(ClassReader.java:400)
at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:88)
at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:106)
... 87 more
为了找到问题的根源,我只是运行客户机单元测试
客户端build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'de.mannodermaus.android-junit5'
apply plugin: 'jacoco'
android {
compileSdkVersion TARGET_SDK_VERION
buildToolsVersion BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion MIN_SDK_VERSION
targetSdkVersion TARGET_SDK_VERION
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
minifyEnabled false
testCoverageEnabled = true
}
}
flavorDimensions 'default'
productFlavors {
full {
dimension = 'default'
}
automation {
dimension = 'default'
}
}
compileOptions {
incremental = false
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions { jvmTarget = "1.8" }
testOptions {
execution 'ANDROID_TEST_ORCHESTRATOR'
animationsDisabled true
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
sourceSets {
main.java.srcDirs += 'src/main/java'
test.java.srcDirs += 'src/test/java'
androidTest.java.srcDirs += 'src/androidTest/java'
}
}
dependencies {
implementation project(path: ':commons')
testApi project(":client:testsupport")
/* MORE DEPENDENCIES NOT RELEVANT TO ISSUE */
}
值得注意的是,我使用的是Dagger 2.25.2
${projectRootDir}/client/build/jacoco/testFullDebugUnitTest.exec 执行数据dir:
源dir:${projectRootDir}/client/src/main/java
${projectRootDir}/client/build/intermediates/javac/fullDebug/classes/,${projectRootDir}/client/build/tmp/kotlin-classes/fullDebug/类类dir:
更新1:从创建一个新分支到将客户端模块中的所有类和测试类重命名为CLASS_NAME.kt.old,我可以确认在IllegalClassFormatException
和no覆盖之间似乎没有任何联系。
更新2:在进一步试验更新1之后,当不依赖子(test)模块(即从gradle文件中移除行testApi project(":client:testsupport")
)时,异常似乎消失了,覆盖率按预期计算。问题是,我需要这个testsupport
模块来执行我的活动测试(这些测试目前没有运行,因为它们在.old文件中,如更新1 ^^所示)。
问题按udate 2更新,如何配置JaCoCo以支持此拉请求中的机器人类的子模块测试实现。
如果需要更多信息,将更新帖子
发布于 2021-01-20 19:29:37
我只是面对着同样的问题。
经过一番调查,它似乎是安卓Gradle插件中的一个bug,只有在使用com.android.library
时才会发生。
我已经在这里报告了它和更多的细节:https://issuetracker.google.com/issues/178015739
虽然Android团队没有修复它,但解决方法是配置
jacoco {
toolVersion = "0.7.9"
}
在build.gradle中
它并不阻止错误被记录,而是使它能够正确地收集覆盖率数据。
发布于 2022-01-10 09:31:48
感谢@Paulo Costa发布链接
对我来说,这是通过增加
plugins {
id 'com.android.library'
id 'jacoco'
}
//these lines
tasks.withType(Test.class).configureEach {
jacoco {
excludes = ["*"]
}
}
贷记:https://issuetracker.google.com/issues/178015739#comment6
https://stackoverflow.com/questions/59378618
复制相似问题