How to add #Generated annotations to delombok code? - java

Sample multi-module project: https://github.com/overfullstack/my-lab/tree/master/lombok-lab
Sample single module project: https://github.com/overfullstack/untitled
I have the following lombok.config:
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
lombok.extern.findbugs.addSuppressFBWarnings = true
But when I see the generated code in build/generated/sources/delombok/java/main/... I don't see #Generated annotations. This is affecting my Jacoco test coverage. Please help. Thanks.
(I observed from my single module project that #Genearated annotations are being added to classes in build/classes/java/main/... but not to build/generated/sources/delombok/java/main/..., is this a bug or expected?)

Related

Pitest gradle, low coverage due to #Data

I tried to get a good coverage file in my java spring project, I mean; see where my tests are good and where they are not. But my problem is that #Data generate a lot of function/class that I don't want to test, and just ruin my coverage.
I already search for a solution, but there is nothing to fix my problem. Looks like Jacoco have something to fix my problem but not Pitest. Maybe Im just not taking the problem right.
Since version 1.2.1 Pitest ignores any method or class annotated with Generated.
You can configure Lombok to add the annotation by adding the following in lombok.config :
lombok.addLombokGeneratedAnnotation = true

Jacoco: Testing #Data annotation in Unit Testing?

After running test and generating coverage report via Jacoco, I realized that there is a static method where a #Data annotation is used and the line of it is marked yellow indicating that it is not tested.
Report
So, is it normal or how can I test that line?
jacoco can ignore code generated by lombok.
put lombok.config in your project’s root
lombok.addLombokGeneratedAnnotation = true
jacoco Release 0.8.0 (2018/01/02)
Methods annotated with #lombok.Generated to better integrate with Lombok >= 1.16.14. Initial analysis and contribution by Rüdiger zu Dohna (GitHub #513).
Methods annotated with #groovy.transform.Generated to better integrate with Groovy >= 2.5.0. Thanks to Andres Almiray for adding the annotation to Groovy (GitHub #610).
jacoco Release 0.8.2 (2018/08/21)
Classes and methods annotated with annotation whose retention policy is runtime or class and whose simple name is Generated are filtered out during generation of report (GitHub #731).
Seems opinion based, but in my opinion there is no point for testing generated code from an external dependency. I would do noting about it and move on.

Sonar + Lombok false positives on #Data annotation

I am getting a lot code smells from lombok generated code in Sonar. F.E.:
Method Dto.hashCode() stores return result in local before immediately returning it
Dto.equals(Object)
is excessively complex, with a cyclomatic complexity of 58
How can I point out sonar that this should be skipped from analyze?
UPDATE
I've tried it already. My lombok.config file in root directory is:
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
lombok.equalsAndHashCode.callSuper = call
It doesn't helps
I've tried it already: sonarqube + lombok = false positives
I've updated: sonar-project.properties in root directory to:
sonar.sources=src/main
sonar.tests=src/test
sonar.language=java
sonar.java.binaries=build/classes
sonar.junit.reportPaths=build/test-results/test/
sonar.jacoco.reportPaths=build/jacoco/jacocoTest.exec
sonar.java.libraries=.gradle/caches/**/lombok-*.jar
It doesn't work either.
Please don't close it. It is not duplication.
I just had the same issue. I am using sonar-scanner and figured out that it needs to set Lombok jar file using command line argument.
For example:
sonar-scanner -D sonar.java.libraries=/home/gitlab-runner/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.10/625fc0055674dff70dbc76efa36d0f2c89b04a24/lombok-1.18.10.jar
Now SonarQube does not show any issues related with Lombok annotations.
Methods generated by lombok need to be annotated with #Generated. Sonarqube will then ignore them.
Just add a file lombok.config in the project root directory, with the following content:
lombok.addLombokGeneratedAnnotation=true
Be sure that lombok.jar is well inside the directory referenced in the sonar.java.libraries property.
I had the same problem, I added the property but I had put a reference to the directory of my runtime package that did not contains the lombok.jar!
lombok.jar is used at compile time and useless at runtime so we avoid to add it inside this directory.

Testing Lombok annotations with Junit

I have a simple Java program which uses the Lombok Annotation - #Builder.
I am testing my code using junit and everytime I run my unit tests, my coverage is always below 50% inspite of the fact that I am testing my entire code.
I looked into the junit generated code coverage and I saw that it was the Lombok annotation which was making the coverage drop.
I see something like:
toString() - 0%
build() - 0%
MyMethod.MyMethodBuilder() - 0%
How do I test these methods for the #Builder annotation? Or the only way to improve coverage is to exclude those from the test coverage?
Starting JaCoCo v0.8.0, you should create lombok.config file to the root of your project and add following content to it:
lombok.addLombokGeneratedAnnotation = true
This will add #Generated annotation to Lombok generated files and JaCoCo will know that code coverage of such a code should be ignored.
Credits to original author here
Create lombok.config file and add texts below:
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
config.stopBubbling = true is telling Lombok that this is the root directory and that it shouldn’t search parent directories for more configuration files (you can have more than one lombok config files in different directories/packages).
lombok.addLombokGeneratedAnnotation = true is telling Lombok to add the #lombok.Generated annotation to all generated methods.
Decompile class which contains lombok annotation to see how lombok has generated source code and then write junits considering that code.
e.g. In case of #ToString, make explicit call to toString method on class object i.e. obj.toString();
Better to use pl.pojo library to test the pojo model classes.

Exclusions not working with Jacoco Gradle plugin

I'm working on setting up the Jacoco Gradle plugin for my project. The plugin is executing fine and generating the coverage report but it's not excluding packages that I would excluded.
Classes I would like to include are in com/xxx/ws/hn/** and classes I would like excluded are in com/xxx/ws/enterprise/**.
Here's my Gradle script:
apply plugin: "jacoco"
jacoco {
toolVersion = "0.6.2.201302030002"
reportsDir = file("$buildDir/reports/jacoco")
}
test {
jacoco{
excludes = ["com/xx/ws/enterprise/**/*"]
includes = ["com/xxx/ws/hn/**/*"]
append = false
}
}
jacocoTestReport {
dependsOn test
description = "Generate Jacoco coverage reports after running tests."
executionData = files('build/jacoco/test.exec')
reports {
xml.enabled true
html.enabled true
}
}
Am I missing anything here? I've tried various patterns of exclusions including a '.' delimiter for packages instead of a '/' but nothing seems to work. Any help would be greatly appreciated.
I have not verified this but when I read the JaCoCo documentation, it states that wildcards can be used but all examples only have ONE *, not two as your example shows.
http://www.eclemma.org/jacoco/trunk/doc/agent.html
To solidify (and verify) Joachim's answer, I came across this SO post and found that specifying canonical class names, classpath style (with slashes, not periods), with single wildcard characters actually worked well. For example, here is my exclude list that works in my build, as defined as a list in a separate gradle file:
def testExcl = [
'android/*',
'com/android/*',
'com/nativelibs4java/*',
'com/ochafik/*',
'com/fasterxml/*',
'com/esotericsoftware/*',
'com/google/*',
'com/lmax/*',
'com/sun/*',
'jdk/*',
'mockit/*',
'org/apache/*',
'org/bridj/*',
'org/gradle/*',
'org/hamcrest/*',
'org/junit/*',
'org/slf4j/*',
'sun/*',
'worker/*',
'*Test',
'*TestIntegration',
'*AllTests',
'*Suite'
]
I tried probably 10 or 12 other ways of formatting the class names, and this is the only way that actually worked.
I don't know why something like this that is so simple/fundamental is so ungoogleable and difficult to find a definitive answer on in the context of Gradle (i.e. outside JaCoCo's official documentation, where no documentation exists about Gradle integration, but Ant and Maven integration docs are there).
Hopefully this helps if others are flailing trying to get JaCoCo to exclude classes.
UPDATE:
This changed in Gradle 7 (I went from 5.6.1 to 7.1.1, so not sure about Gradle 6) and no longer works.
For Gradle 7 you need to replace / with .; here are my updated exclusions:
def testExcl = [
'android.*',
'com.android.*',
'com.nativelibs4java.*',
'com.ochafik.*',
'com.fasterxml.*',
'com.esotericsoftware.*',
'com.google.*',
'com.lmax.*',
'com.sun.*',
'jdk.*',
'mockit.*',
'org.apache.*',
'org.bridj.*',
'org.gcpud.common.*',
'org.gcpud.testutil.*',
'org.gradle.*',
'org.hamcrest.*',
'org.junit.*',
'org.slf4j.*',
'sun.*',
'worker.*',
'*Test',
'*Test$*',
'*TestIntegration',
'*AllTests',
'*Suite'
]
Also see the following SO post for other means of excluding classes from reporting (exclude from reporting, not coverage itself):
Filter JaCoCo coverage reports with Gradle

Categories

Resources