JaCoCo coverage verification after multiple test Gradle tasks - gradle

In my Java (Gradle-based) project, I have the default test task and custom defined integrationTest task. My build.gradle looks following
plugins {
id 'de.jansauer.printcoverage' version '2.0.0'
}
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'jacoco'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceSets {
integration {
java.srcDir "$projectDir/src/integration/java"
resources.srcDir "$projectDir/src/integration/resources"
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
}
}
configurations {
integrationImplementation.extendsFrom testImplementation
integrationImplementation.canBeResolved true
integrationRuntimeOnly.extendsFrom testRuntimeOnly
integrationRuntimeOnly.canBeResolved true
}
task integrationTest(type: Test) {
description = 'Runs the integration tests.'
group = 'verification'
testClassesDirs = sourceSets.integration.output.classesDirs
classpath = sourceSets.integration.runtimeClasspath
outputs.upToDateWhen { false }
useJUnitPlatform()
}
idea {
module {
testSourceDirs += sourceSets.integration.java.srcDirs
testResourceDirs += sourceSets.integration.resources.srcDirs
}
}
check.dependsOn integrationTest
repositories {
mavenCentral()
}
dependencies {
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.8.2'
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.4.6'
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '3.4.6'
testImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.4.6'
}
test {
useJUnitPlatform()
finalizedBy jacocoTestCoverageVerification, printCoverage
}
jacocoTestReport {
reports.xml.enabled true
}
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 1.0
}
}
}
}
In general, it works fine, but there is a problem. Sometimes there are places in code that are really difficult to unit-test, and are great for integration tests. However, JaCoCo counts only coverage in unit tests. I could place finalizedBy jacocoTestCoverageVerification, printCoverage in the integrationTest task, but then I'd have two separate coverages.
My goal is to have one common coverage from both test configuration. I tried changing finalizedBy to dependsOn (with adequate logic change), but then I had no coverage at all. I don't know if it's even possible tbh, but I'm guessing it is.

Related

Open webpages generated by restdocs

I want to display static pages using Spring Boot. I tried this configuration:
plugins {
id "java"
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
repositories {
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
mavenCentral()
mavenLocal()
}
group = 'com.example'
sourceCompatibility = 11
targetCompatibility = 11
ext {
restdocsVersion = '3.0.0-SNAPSHOT'
snippetsDir = file('src/static/docs')
}
configurations {
asciidoctorExtensions
}
dependencies {
asciidoctorExtensions "org.springframework.restdocs:spring-restdocs-asciidoctor:$restdocsVersion"
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.6.3'
implementation 'io.projectreactor.netty:reactor-netty-http:1.0.15'
testImplementation 'io.rest-assured:rest-assured:4.5.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0'
testImplementation "org.springframework.restdocs:spring-restdocs-restassured:$restdocsVersion"
testImplementation 'org.springframework:spring-test'
testImplementation('org.junit.vintage:junit-vintage-engine') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0'
}
test {
outputs.dir snippetsDir
useJUnitPlatform()
}
asciidoctor {
configurations "asciidoctorExtensions"
inputs.dir snippetsDir
dependsOn test
}
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
I placed several .adoc files under this file location:
I started the project as a Spring Boot project but when I open http://localhost:8080/docs/index.html I get white label error:
Do you know how I can serve this content as web pages?

why I could not refer ext properties in subproject

when I import spring cloud mavenBom,if I use code:
subprojects {
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
ext {
springCloudVersion = "Hoxton.SR8"
}
repositories {
maven { url 'https://maven.aliyun.com/repository/public/' }
mavenLocal()
mavenCentral()
}
dependencyManagement{
dependencies {
dependency(group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.7.RELEASE'){
exclude group: 'log4j', name: 'log4j', version: '1.2.16'
}
dependency(group: 'log4j', name: 'log4j', version: '1.2.17')
dependency('org.projectlombok:lombok:1.18.2')
}
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}'
}
}
}
it doesn't work, and the error is :
Could not find org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}.
if I transform ${springCloudVersion} to Hoxton.SR8,it work absolutely.
so, what result in this case?
If you want ${springCloudVersion} to be interpreted, you need a GString (use double quote ")
https://groovy-lang.org/syntax.html#_double_quoted_string
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"

Gradle multiple project gradle build fail with lombok 1.8.10 but compile well

I'm developing a gradle-multiple-project java application, code works well with lombok in intellij (getter, setter method is visible), but when I run gradle build then fail, get the message:
~/EventStormingWorkShop/sources/coffeeshop/coffee-domain/src/main/java/solid/humank/port/adapter/OrderReceiverAdapter.java:41: error: cannot find symbol
String orderString= mapper.writeValueAsString(orderCreatedEvent.getDetail());
^
symbol: method getDetail()
location: variable orderCreatedEvent of type OrderCreatedEvent
Current environment:
Intellij : 2019.2.3
Gradle : 5.6.2
JDK : GraalVM 19.2.0 (compatible with JDK 1.8_0222)
lombok : 1.8.10
I had checked the lombok dependencies declaration in build.gradle.
compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
at compile time everything wen well.
Here is the build.gradle from my rootProject
buildscript {
ext {
quarkusJunitVersion = '0.22.0'
restAssuredVersion = '3.3.0'
cucumberVersion = '4.7.1'
lombokVersion = '1.18.10'
quarkusVersion = '0.23.1'
awsJavaVersion = '1.11.631'
awsVersion = '2.5.29'
}
}
apply from: file("${rootDir}/gradle/project.gradle")
List testCompilePackage = ["io.quarkus:quarkus-junit5:${quarkusJunitVersion}", "io.rest-assured:rest-assured:${restAssuredVersion}"]
List testImplementPackage = ["io.cucumber:cucumber-java8:${cucumberVersion}", "io.cucumber:cucumber-junit:${cucumberVersion}"]
List implementationPackage = ["io.quarkus:quarkus-resteasy",
"com.amazonaws:aws-java-sdk-lambda",
"com.amazonaws:aws-java-sdk-dynamodb",
"com.amazonaws:aws-lambda-java-core",
"com.amazonaws:aws-lambda-java-events",
"com.amazonaws:aws-java-sdk-events"]
subprojects { dir ->
repositories {
mavenCentral()
}
dependencies {
// Lombok Support
compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
// quarkus test
testCompile testCompilePackage
// cucumber test
testImplementation testImplementPackage
// quarkus
compile group: 'io.quarkus', name: 'quarkus-gradle-plugin', version: "${quarkusVersion}", ext: 'pom'
implementation enforcedPlatform("io.quarkus:quarkus-bom:${quarkusVersion}")
implementation platform("com.amazonaws:aws-java-sdk-bom:${awsJavaVersion}")
implementation platform("software.amazon.awssdk:bom:${awsVersion}")
implementation implementationPackage
}
if (dir.name.endsWith("-domain")) {
dependencies {
implementation project(":ddd-commons")
}
}
if (dir.name.endsWith("-application")) {
String modName = dir.name.substring(0, dir.name.lastIndexOf("-application"))
dependencies {
implementation project(":ddd-commons"), project(":${modName}-domain")
}
}
if (dir.name.endsWith("-web")) {
String modName = dir.name.substring(0, dir.name.lastIndexOf("-web"))
dependencies {
implementation project(":ddd-commons"), project(":${modName}-domain"), project(":${modName}-application")
}
}
}
The build.gradle will apply a project.gradle file
project.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'io.quarkus:quarkus-gradle-plugin:0.23.1'
}
}
defaultTasks 'clean', 'build'
apply plugin: 'idea'
subprojects {
apply plugin: 'java'
apply plugin: io.quarkus.gradle.QuarkusPlugin
group 'solid.humank.coffeeshop'
version '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
idea.module.inheritOutputDirs = true
dependencies{
compileOnly "org.projectlombok:lombok:1.18.10"
annotationProcessor "org.projectlombok:lombok:1.18.10"
testCompileOnly "org.projectlombok:lombok:1.18.10"
testAnnotationProcessor "org.projectlombok:lombok:1.18.10"
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
options.deprecation = true
options.compilerArgs += ['-Xlint:none', '-proc:none', '-nowarn']
}
repositories {
mavenCentral()
mavenLocal()
}
buildDir = "${rootDir}/build/${rootDir.relativePath(projectDir)}"
tasks.named('test') {
useJUnitPlatform()
failFast = true
testLogging.showStandardStreams = true
testLogging.exceptionFormat 'full'
}
tasks.named('jar') {
// put parent name in final jar name, to resolve collision of child projects with same name under different parents
if (parent.depth > 0) {
archiveBaseName = "${parent.name}-${archiveBaseName.get()}"
}
}
afterEvaluate {
def buildTime = new Date()
tasks.withType(Jar) {
String ClassPathString = ''
configurations.runtime.each { ClassPathString += " lib\\" + it.name }
manifest {
attributes 'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Created-By': "${System.getProperty('java.version')} (${System.getProperty('java.vendor')})",
'Built-With': "gradle-${project.gradle.gradleVersion}, groovy-${GroovySystem.version}",
'Built-By': System.getProperty('user.name'),
'Built-On': "${InetAddress.localHost.hostName}/${InetAddress.localHost.hostAddress}",
'Build-Time': buildTime.format('yyyy/MM/dd HH:mm:ss'),
'Class-Path': ClassPathString
}
}
}
}
Besides, there is the settings.gradle to include sub projects
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'io.quarkus') {
useModule("io.quarkus:quarkus-gradle-plugin:0.23.1")
}
}
}
}
rootProject.name = 'coffeeshop'
include 'ddd-commons'
include 'inventory-domain'
include 'inventory-application'
include 'inventory-web'
include 'coffee-application'
include 'coffee-domain'
include 'coffee-web'
include 'orders-application'
include 'orders-domain'
include 'orders-web'
I expect these settings could run gradle build well, but faced seems lombok annotation processer not worked issue in gradle runtime.
Because your project.gradle has '-proc:none'

How to correctly run gradle test task?

I try to build my project with gradle when I run gradle test from Intellij Idea everything is fine - all tests are passed but when I do the same operation from command line using command gradle test some unit tests failed. That is my build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'myProjectName'
}
repositories {
mavenCentral()
maven {
url "my_repo_url"
}
maven {
url "my_repo_url"
credentials {
username = System.getenv("MVN_USER")
password = System.getenv("MVN_PASS")
}
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile ('org.apache.poi:poi-ooxml:4.0.1')
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile ('org.springframework.boot:spring-boot-starter:2.0.5.RELEASE') {
exclude module : 'spring-boot-starter-logging'
}
compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: '4.0.1'
testCompile('org.springframework.boot:spring-boot-starter-test:2.0.1.RELEASE')
testCompile('com.jayway.jsonpath:json-path')
testCompile group: 'commons-io', name: 'commons-io', version: '2.6'
testCompile group: 'pl.pragmatists', name: 'JUnitParams', version: '1.1.1'
compile group: 'joda-time', name: 'joda-time', version: '2.9.4'
}
and there is my junit test class:
public class MyTest {
#Test
public void testSimpleIfParsing() throws IOException {
String complicatedStructure = "testString";
IfTemplateElement MyClass = new MyClass(
complicatedStructure // This variable NOT null, but I have NullPointerException
);
Object response = MyClass.evaluate();
Assert.assertNotNull( response );
}
}
and MyClass constructor:
public class MyClass {
public MyClass( String s ) {
s = s.substring( 0, 5 ); // there I have NullPointerException.
}
}
Exception:
com.mypackage.MyTest > testSimpleIfParsing FAILED
java.lang.NullPointerException at MyTest.java:28
but if in the MyClass in the constructor I insert System.out.println(s) all tests passed in both cases (from CLI and Intellij Idea).
Can anyone help me what is goin on?
Where I mistake?
Sounds strange.
I suggested that you will try to debug the UT with intelij and after that try with gradle.
How to change the unit test runner in inteliJ?
Go to settings -> Build,Execution,Deployment > Build Tools > Gradle > Runner

integrationTestCompile gradle dependency ignored

Following a few blog posts I tried to create a separate source folder for integration testing in gradle. I wanted also to add some additinal (arquillian) dependencies to my integrationTest task, but the integrationTestCompile seems to be ignored and I get a compilation error with the additional dependecy not resolved. When I change the dependecy to testCompile it works fine. Why is that so and how to change it? My simple test class:
//compilation fails with [Static type checking] - The variable [ArquillianSputnik] is undeclared
#TypeChecked
#RunWith(ArquillianSputnik)
class TestSpec extends Specification {
}
and gradle.build:
apply plugin: 'groovy'
apply plugin: 'war'
war.dependsOn 'native2ascii'
task native2ascii << {
ant.delete() {
fileset(dir: "${processResources.destinationDir}") {
include(name: '*.properties')
}
}
ant.native2ascii(src: 'src/main/resources/',
dest: "${processResources.destinationDir}",
includes: '**/*.properties',
encoding: 'UTF-8')
}
repositories {
mavenCentral()
maven {
url 'http://repository.jboss.org/nexus/content/groups/public'
}
mavenLocal()
}
sourceSets.main.java.srcDirs = []
sourceSets.main.groovy.srcDirs += ["src/main/java"]
sourceSets {
integrationTest {
groovy.srcDir file('src/integration-test/groovy')
resources.srcDir file('src/integration-test/resources')
compileClasspath = sourceSets.main.output + configurations.testCompile
runtimeClasspath = output + compileClasspath + configurations.testRuntime
}
}
dependencies {
//(...) non-test dependencies cut out for clarity
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'cglib:cglib-nodep:2.2.2'
testCompile 'org.objenesis:objenesis:1.2'
//when integrationTestCompile is changed to testCompile the compilation works and the test is executed
integrationTestCompile 'org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.Beta3'
integrationTestCompile 'org.jboss.arquillian.graphene:graphene-webdriver:2.0.3.Final'
integrationTestCompile 'org.jboss.as:jboss-as-arquillian-container-managed:7.2.0.Final'
}
task integrationTest(type: Test, dependsOn: 'test') {
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn 'integrationTest'
First, you want to add to the compile and runtime classpaths rather than replace them. This really just means using the += operator rather than the = one. Additionally, you really only want to add the other sourcesets output, we'll deal with configurations separately.
compileClasspath += sourcesets.main.output + sourcesets.test.output
runtimeClasspath += sourcesets.main.output + sourcesets.test.output
Next, we'll want to configure our integration test configurations. Usually, this just means making them extend the test and compile ones so that they contain all those dependencies as well.
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}

Resources