Open BenjaminZaiser opened 8 years ago
Not sure. It's the class files being transformed so you don't have any correct sources to compare against. You could write a tool that modifies the test coverage file to convert the classes back to whatever the java 8 lambda representation would be. Not sure how much work that would be.
+1 I really wish I knew this plugin broke Jacoco before I started to use it :(.
@evant How difficult would that be?
@BenjaminZaiser Check out this project: https://github.com/maurizi/Geoclock
It looks like the following combinations work:
The Repo:
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.0'
and mine:
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.0'
Once you bump the retrolambda plugin to 3.2.1
, it no longer works.
I modified the jacoco
task to filter the Lambdas
that are auto-generated
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebugUnitTest") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class',
'**/Lambda$*.class',
'**/Lambda.class',
'**/*Lambda.class',
'**/*Lambda*.class'
])
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files('build/jacoco/testDebugUnitTest.exec')
}
@evant I have tried the following versions:
Works:
classpath 'me.tatarka:gradle-retrolambda:3.2.0'
Fails to produce jacoco:
classpath 'me.tatarka:gradle-retrolambda:3.2.1'
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
classpath 'me.tatarka:gradle-retrolambda:3.3.0-beta3'
@evant @BenjaminZaiser Using:
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.4' // latest that is not in beta
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
and:
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebugUnitTest") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
def autoGenerated = ['**/R.class',
'**/R$*.class',
'**/Manifest*.*',
'android/**/*.*',
'**/BuildConfig.*',
'**/*$ViewBinder*.*',
'**/*$ViewInjector*.*',
'**/Lambda$*.class',
'**/Lambda.class',
'**/*Lambda.class',
'**/*Lambda*.class']
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: autoGenerated)
// additionalSourceDirs = files(coverageSourceDirs) // should not matter
sourceDirectories = files(coverageSourceDirs)
executionData = files('build/jacoco/testDebugUnitTest.exec')
}
I got it to work!
Thanks for your comment, but I don't know how you got it to work so the anonymous classes (mentioned in the exec file) are mapped to the lambdas in the code?
@BenjaminZaiser Yes. I exclude them out. What do you need help with?
@evant I think this can be closed now.
But then the overall code coverage is wrong (or way below the actual code coverage), because the code inside the lambdas is not analyzed; you don't know if the code inside the lambdas was executed or not.
@BenjaminZaiser It is the not the best but it is very close.
Hello, i've improved gradle script for Jacoco, please see here: https://gist.github.com/ultraon/54cca81ca159ed0a4a9ebf62e89c26ba
This seems to break again when I use a newer version than 3.2.4 (tried 3.3.1 and 3.4.0). Currently I use 3.2.4 in combination with retrolambda 2.3.0 and got it to work (with the configuration from @ultraon 👍 ).
When I use a newer version I get either an IllegalAccessError for $jacocoData
or a NoSuchMethodError if I don't use defaultMethods
also for $jacocoData
(or $jacocoInit
).
The errors are raised for the methods on an Interface.
I confirm. When using version 3.2.4 I get proper jacoco reports. when I change to 3.2.5 or any higher (up to 3.5.0) jacoco code coverage shows reduction from 73% to 34%. Going through particular tests it seems like with retrolambda many tests are not triggered and therefore there are no results, ergo 0% of coverage.
[Edit] Also, i checked changes between 3.2.4 and 3.2.5 and it seems that changes in groovy files are the reason, not versions bumps, but I am not able to conclude which line causes the problem
Would appreciate this mentioned in the Known Issues section of the README, since generating coverage reports is a fairly common task and fixing this issue doesn't seem to be a priority... (personally it would have saved me some debug time - I image others too)
We're seeing this again/still on grandle-retrolambda
3.6.0 with retrolambda
2.5.1.
I did some further digging and found that retrolambda can, under some circumstances, move the jacoco-added method $jacocoInit()
from our class Foo
into a newly generated class Foo$
which the program when running of course can not find.
Our workaround for now is to make separate builds for instrumentation and for actually running, but this is slightly silly.
Any update on this?
We are using Retrolambda in our app (which is really awesome and makes our code much cleaner) along with the jacoco plugin to gather the code coverage of our acceptance tests (see also http://stackoverflow.com/questions/30976319/android-gradle-jacoco-offline-instrumentation-for-integration-tests).
So we are
Then Jacoco writes the coverage information to an exec file. This file contains a list of classes which were executed during the tests, e.g. com/ecma/app/service/Manager or com/ecma/app/model/Model$$Lambda$15
When SonarQube then tries to calculate the code coverage by comparing the coverage information with the source code, it will fail, because there is no anonymous class Model$$Lambda$15 in the source code.
Is there a way to fix this problem?
Thanks Ben