I have the following classes in separated files:
#Path("/products")
#Produces(MediaType.APPLICATION_JSON)
class ProductController{
#Inject
private ProductService productService;
}
#ApplicationScoped
public class ProductService {
#Inject
private ProductRepository productRepository;
}
#ApplicationScoped
public class ProductRepository implements PanacheRepositoryBase<Product, UUID> {
}
And when I run the tests coverage, all controllers and services and other packages are correctly recognized by JaCoCo, but all repositories aren't, resulting in 0% coverage in this package. And I'm sure that they are being used by services.
My guess is because JaCoCo only recognizes up to 1 level of "proxy", due to #AppicationScoped annotation, but I'm not sure.
I also tried offline intrumentation, but the result is the same.
This is my gradle config now:
plugins {
id 'java'
id 'io.quarkus'
id 'jacoco'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
// a lot of deps not related to tests
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
}
compileTestJava {
options.encoding = 'UTF-8'
}
test {
useJUnitPlatform()
jacoco {
destinationFile = file("$buildDir/jacoco/test.exec")
}
finalizedBy jacocoTestReport
}
jacoco {
toolVersion = '0.8.6'
reportsDir = file("$buildDir/reports/jacoco")
}
jacocoTestCoverageVerification {
executionData fileTree("$buildDir/jacoco/").include("*.exec")
afterEvaluate {
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it)
}))
}
}
jacocoTestReport {
executionData fileTree("$buildDir/jacoco/").include("*.exec")
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/reports/jacoco")
}
afterEvaluate {
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it)
}))
}
}
And this is the other "version" of gradle config, with offline instrumentation:
configurations {
jacocoAnt
jacocoRuntime
}
dependencies {
jacocoAnt group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.5', classifier: 'nodeps'
jacocoRuntime group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.5', classifier: 'runtime'
}
test {
useJUnitPlatform()
jacoco {
destinationFile = file("$buildDir/reports/jacoco/jacoco-sonar/jacoco-coverage.exec")
}
}
jacoco {
toolVersion = "0.8.5"
reportsDir = file("$buildDir/customJacocoReportDir")
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
}
jacocoTestCoverageVerification {
executionData fileTree("$buildDir/reports/jacoco/jacoco-sonar/").include("*.exec")
afterEvaluate {
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it)
}))
}
violationRules {
rule {
limit {
minimum = 0.74
}
}
}
}
task instrument(dependsOn: ['classes']) {
ext.outputDir = buildDir.path + '/reports/classes-instrumented'
doLast {
ant.taskdef(name: 'instrument',
classname: 'org.jacoco.ant.InstrumentTask',
classpath: configurations.jacocoAnt.asPath)
ant.instrument(destdir: outputDir) {
sourceSets.main.output.classesDirs.each { fileset(dir: it) }
}
}
}
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(instrument)) {
tasks.withType(Test) {
doFirst {
classpath = files(instrument.outputDir) + classpath + configurations.jacocoRuntime
}
}
}
}
task report(dependsOn: ['instrument', 'test']) {
doLast {
ant.taskdef(name: 'report',
classname: 'org.jacoco.ant.ReportTask',
classpath: configurations.jacocoAnt.asPath)
ant.report() {
executiondata {
ant.file(file: buildDir.path + '/reports/jacoco/jacoco-sonar/jacoco-coverage.exec')
}
structure(name: 'Example') {
classfiles {
sourceSets.main.output.classesDirs.each { fileset(dir: it) }
}
sourcefiles {
fileset(dir: 'src/main/java')
}
}
html(destdir: buildDir.path + '/reports/jacoco')
}
}
}
Why it happens?
I was facing the same problem as you, after include the following extension the coverage problem for #ApplicationScoped annotated classes was solved.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jacoco</artifactId>
<scope>test</scope>
</dependency>
Obviously, since you are using Gradle, you should change it. I also needed to remove jacoco-maven-plugin plugin from maven plugins section. Probably you will need to remove everything that you included for custom instrumentation.
Quarkus bytecode instrumentation and JaCoCo can step on each other toes, JaCoCo default mode uses an agent the inject some bytecode and this can be incompatible with Quarkus' own bytecode injection.
You can switch JaCoCo to offline instrumentation instead, please follow this section of the Quarkus test coverage guide:
https://quarkus.io/guides/tests-with-coverage#instrumenting-the-classes-instead
Related
I am having a Gradle spring-boot project and getting the following error when starting the application.
Ran this cmd: gradle clean bootRun --warning-mode all
ptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
14:06:27.154 [restartedMain] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.IllegalArgumentException: Unable to instantiate factory class: org.springframework.boot.env.EnvironmentPostProcessor
at org.springframework.core.io.support.SpringFactoriesLoader.instantiateFactory(SpringFactoriesLoader.java:167)
at org.springframework.core.io.support.SpringFactoriesLoader.loadFactories(SpringFactoriesLoader.java:104)
at org.springframework.boot.context.config.ConfigFileApplicationListener.loadPostProcessors(ConfigFileApplicationListener.java:183)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ConfigFileApplicationListener.java:173)
at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent(ConfigFileApplicationListener.java:163)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:347)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at app.EventsApplication.main(EventsApplication.java:25)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.NoSuchMethodException: org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3349)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2553)
at org.springframework.util.ReflectionUtils.accessibleConstructor(ReflectionUtils.java:530)
at org.springframework.core.io.support.SpringFactoriesLoader.instantiateFactory(SpringFactoriesLoader.java:164)
... 20 common frames omitted
BUILD SUCCESSFUL in 7s
I tried updating to the newer version of gradle to springboot and even deleted the local cache. Restarted the intellij by invalidating the cache etc,but no luck.
This is the build.gradle file.
buildscript {
dependencies {
classpath 'org.postgresql:postgresql:42.2.24'
classpath 'com.smartnews:jpa-entity-generator:0.99.8'
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.4.0.RELEASE")
}
}
plugins {
// id 'com.diffplug.spotless' version '5.15.1'
id 'com.github.ben-manes.versions' version '0.39.0'
id 'com.github.johnrengelman.processes' version '0.5.0'
id 'com.github.spotbugs' version '4.7.5'
id 'com.star-zero.gradle.githook' version '1.2.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.flywaydb.flyway' version '7.15.0'
id 'org.springframework.boot' version '2.4.0'
id 'org.owasp.dependencycheck' version '6.3.2'
id 'org.sonarqube' version '3.3'
id 'org.springdoc.openapi-gradle-plugin' version '1.3.3'
id 'pl.allegro.tech.build.axion-release' version '1.13.3'
id 'ru.netris.commitlint' version '1.4.1'
id 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' version '1.71.4'
id 'checkstyle'
id 'java'
id 'jacoco'
id 'pmd'
}
group = 'app'
version = "1.0.0"
//sourceCompatibility = '11' VERSION_11
java.sourceCompatibility = JavaVersion.VERSION_11
apply plugin: 'entitygen'
repositories {
mavenCentral()
// mavenLocal()
maven {
url "http://nexus.infra.cloud.247-inc.net:8080/nexus/repository/greleases/"
allowInsecureProtocol = true
}
}
sourceSets {
integrationTest {
compileClasspath += main.output
runtimeClasspath += main.output
}
smokeTest {
compileClasspath += main.output
runtimeClasspath += main.output
}
}
processResources {
filesMatching("**/application.properties") {
expand(project.properties)
}
}
dependencies {
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
implementation 'assist:kafka-connector:4.0.0'
implementation 'org.projectlombok:lombok:1.18.22'
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'io.springfox:springfox-swagger-ui:3.0.0'
runtimeOnly 'org.postgresql:postgresql:42.2.24'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.assertj:assertj-core:3.21.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.testcontainers:testcontainers:1.16.0'
testImplementation 'org.testcontainers:junit-jupiter:1.16.0'
testImplementation 'org.testcontainers:postgresql:1.16.0'
developmentOnly("org.springframework.boot:spring-boot-devtools")
integrationTestImplementation sourceSets.main.runtimeClasspath
integrationTestImplementation sourceSets.test.runtimeClasspath
smokeTestImplementation sourceSets.main.runtimeClasspath
smokeTestImplementation sourceSets.test.runtimeClasspath
}
githook {
failOnMissingHooksDir = false
hooks {
'commit-msg' {
task = 'commitlint'
}
}
}
openApi {
outputDir = file('build/docs')
}
bootBuildImage {
imageName = 'spring-api:latest'
}
checkstyle {
toolVersion = '9.0'
configFile = file('checkstyle.xml')
}
pmd {
toolVersion = '6.38.0'
ignoreFailures = true
}
//spotless {
// java {
// target 'src/**/*.java'
// importOrder()
// removeUnusedImports()
// prettier([
// 'prettier': '2.4.1',
// 'prettier-plugin-java': '1.4.0'
// ]).configFile('.prettierrc')
// }
//}
spotbugs {
toolVersion = '4.4.1'
ignoreFailures = true
}
sonarqube {
properties {
property 'sonar.projectKey', 'voice-reporting-events-generator'
property 'sonar.projectName', 'voice-reporting-events-generator'
property "sonar.sourceEncoding", "UTF-8"
property "sonar.jacoco.reportPath", "./build/jacoco/test.exec"
property "sonar.host.url", "http://sonar.cicd.247-inc.net:8080"
property "sonar.sources", "./src/main/java"
property "sonar.tests", "./src/test/java"
property "sonar.java.binaries", "./build/classes/java/main/"
property "sonar.java.test.binaries", "./build/classes/java/test/"
property "sonar.inclusions", "**/*.java"
property "sonar.exclusions", "**/*Generated.java"
property "http.proxyHost", "10.64.99.240"
property "http.proxyPort", "3128"
property "https.proxyHost", "10.64.99.240"
property "https.proxyPort", "3128"
}
}
flyway {
url = DB_URL
user = DB_USER
password = DB_PASSWORD
}
entityGen {
configPath = 'src/main/resources/db/entity-generator.yaml'
}
jacoco {
toolVersion = '0.8.7'
}
jacocoTestReport {
dependsOn test
finalizedBy jacocoTestCoverageVerification
reports {
xml.required = true
}
}
jacocoTestCoverageVerification {
dependsOn test
violationRules {
rule {
limit {
minimum = 0.5
}
}
}
}
test {
finalizedBy jacocoTestReport
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}
task integrationTest(type: Test) {
description = 'Runs the integration tests.'
group = 'Verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}
task smokeTest(type: Test) {
description = 'Runs the smoke tests.'
group = 'Verification'
testClassesDirs = sourceSets.smokeTest.output.classesDirs
classpath = sourceSets.smokeTest.runtimeClasspath
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}
task generateEntities(type: Exec) {
description = 'Generates the entities sources.'
group = 'Build'
commandLine './gradlew', 'entityGen', 'format'
environment([DB_URL: DB_URL, DB_USER: DB_USER, DB_PASSWORD: DB_PASSWORD])
doLast {
ant.replace(token: '\\\"', value: '') {
fileset(dir: 'src/main/java/app/entity')
}
}
}
task lint() {
dependsOn 'formatCheck', 'checkstyle' , 'pmd', 'spotbugs'
description = 'Runs several static code analysis.'
group = 'Verification'
}
task checkstyle() {
dependsOn 'checkstyleIntegrationTest', 'checkstyleMain', 'checkstyleSmokeTest', 'checkstyleTest'
description = 'Runs Checkstyle analysis for the source folder.'
group = 'Verification'
}
task pmd() {
dependsOn 'pmdIntegrationTest', 'pmdMain'
description = 'Runs PMD analysis for the source folder.'
group = 'Verification'
}
task spotbugs() {
dependsOn 'spotbugsIntegrationTest', 'spotbugsMain', 'spotbugsSmokeTest', 'spotbugsTest'
description = 'Runs SpotBugs analysis for the source folder.'
group = 'Verification'
tasks.withType(com.github.spotbugs.snom.SpotBugsTask) {
reports {
html.enabled = true
}
}
}
task format() {
dependsOn 'spotlessApply'
description = 'Applies code formatting steps to source code in-place.'
group = 'Verification'
}
task formatCheck() {
dependsOn 'spotlessCheck'
description = 'Checks that source code satisfies formatting steps.'
group = 'Verification'
}
task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) {
description = 'Generates a changelog from GIT repository.'
group = 'Release'
fromRepo = file('.')
file = file('CHANGELOG.md');
templateContent = file('changelog.mustache').getText('UTF-8');
}
task deploy(type: Exec) {
commandLine 'ansible-playbook', 'cicd/deploy/deploy-to-swarm.yaml'
description = 'Deploys the application to Docker Swarm.'
group = 'Release'
}
jar {
baseName = 'base-name'
version = '1.0.0'
manifest {
attributes 'Main-Class': 'app.EventsApplication'
}
}
task fatJar(type: Jar) {
manifest.from jar.manifest
// classifier = 'all'
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
artifacts {
archives fatJar
}
springBoot {
buildInfo()
}
bootJar {
archiveBaseName = rootProject.name
archiveVersion = rootProject.version
}
ext {
set('springCloudVersion', "Hoxton.SR8")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
I am trying to run the test for java applications (with module system enabled) using Gradle and getting the following error.
java.lang.IllegalAccessError: class org.junit.platform.launcher.core.LauncherFactory (in unnamed module #0x7cd3a5) cannot access class org.junit.platform.commons.util.Preconditions (in module org.junit.platform.commons) because module org.junit.platform.commons does not export org.junit.platform.commons.util to unnamed module #0x7cd3a5
Error says module org.junit.platform.commons does not export org.junit.platform.commons.util
This is how my build file looks like:
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'java'
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id "org.beryx.jlink" version "2.21.0"
id "org.javamodularity.moduleplugin" version "1.6.0"
}
repositories {
gradlePluginPortal()
jcenter()
}
sourceCompatibility = JavaVersion.VERSION_14
targetCompatibility = JavaVersion.VERSION_14
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
jar {
enabled = true;
}
application{
mainModule='com.sudhir.registration'
}
test {
useJUnitPlatform()
}
configurations {
springFactoriesHolder { transitive = false }
}
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
}
}
dependencies {
springFactoriesHolder 'org.springframework.boot:spring-boot-actuator-autoconfigure'
springFactoriesHolder 'org.springframework.boot:spring-boot-autoconfigure'
springFactoriesHolder 'org.springframework.boot:spring-boot'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
exclude group: 'com.vaadin.external.google', module: 'android-json'
}
}
mainClassName = "com.sudhir.registration.ApiApplication"
prepareMergedJarsDir.doLast {
// extract and merge META-INF/spring.factories from springFactoriesHolder
def factories = configurations.springFactoriesHolder.files.collect {
def props = new Properties()
props.load(zipTree(it).matching { include 'META-INF/spring.factories' }.singleFile.newInputStream())
props
}
def mergedProps = new Properties()
factories.each { props ->
props.each { key, value ->
def oldVal = mergedProps[key]
mergedProps[key] = oldVal ? "$oldVal,$value" : value
}
}
def content = mergedProps.collect { key, value ->
def v = (value as String).replace(',', ',\\\n')
"$key=$v"
}.join('\n\n')
mkdir("$jlinkBasePath/META-INF")
new File("$jlinkBasePath/META-INF/spring.factories").text = content
// insert META-INF/spring.factories into the main jar
ant.zip(update: "true", destfile: jar.archivePath, keepcompression: true) {
fileset(dir: "$jlinkBasePath", includes: 'META-INF/**')
}
}
jlink {
imageZip = file("$buildDir/image-zip/registration-service-image.zip")
options = ['--strip-java-debug-attributes', '--compress', '2', '--no-header-files', '--no-man-pages']
forceMerge 'jaxb-api', 'byte-buddy', 'classgraph'
mergedModule {
uses 'ch.qos.logback.classic.spi.Configurator'
excludeRequires 'com.fasterxml.jackson.module.paramnames'
excludeProvides implementation: 'com.sun.xml.bind.v2.ContextFactory'
excludeProvides servicePattern: 'javax.enterprise.inject.*'
excludeProvides service: 'org.apache.logging.log4j.spi.Provider'
excludeProvides servicePattern: 'reactor.blockhound.integration.*'
}
launcher {
name = 'run'
jvmArgs = [
'--add-reads', 'registration.service.merged.module=com.sudhir.registration',
'-cp', 'config/',
]
}
}
tasks.jlink.doLast {
copy {
from "src/main/resources"
into "$imageDir.asFile/bin/config"
}
copy {
from "$buildDir/classes/java/main/com/sudhir/registration"
into "$imageDir.asFile/bin/config/com/sudhir/registration/for-spring-classpath-scanner"
}
}
However, I am able to run specific tests in IntelliJ. I think it's because Intellij is using classpath instead of module path.
I am using gradle-module-system plugin to build, test and run. sample code can be found here.
Can someone please assist me how to deal with this issue. I am very new to using java module system.
Not quite sure on the reason of this problem. These threads may help to understand it: this, this, this or this
But this is what helped me in a similar case:
test {
moduleOptions {
runOnClasspath = true
}
useJUnitPlatform()
}
(Adding moduleOptions setting to the test task)
I have this root build.gradle
repositories {
jcenter()
}
subprojects {
apply plugin: 'java'
group 'me.someone'
version '1.0.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
jcenter()
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.12'
}
}
Then I have this child build.gradle
plugins {
id 'java-library'
id 'eclipse'
id "org.springframework.boot" version "2.0.1.RELEASE"
id 'io.spring.dependency-management' version "1.0.5.RELEASE"
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile project(':foo-jar')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation group: 'org.mockito', name: 'mockito-core', version: '2.18.3'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
test {
java.srcDir file('src/int/java')
}
itest {
java {
srcDir file('src/itest/java')
}
//resources.srcDir 'src/itest/resources'
}
}
test {
testLogging {
showStandardStreams = true
events "passed", "skipped", "failed"
exceptionFormat = 'full'
}
}
task itest(type: Test) {
testLogging {
showStandardStreams = true
events "passed", "skipped", "failed"
exceptionFormat = 'full'
}
itest.mustRunAfter test
}
check.dependsOn itest
bootRun {
main = 'me.someone.BarServiceApplication'
}
The issue is unit test runs twice but not the integration test. Why is unit test running twice but not integration test? My understanding is when I provided the source folder of integration test, it should run the integration test as well.
Your task itest needs to have its testClassesDirs configured, that is why it is currently running your unit tests twice. It might also need the classpath configured.
And you should have a look at the Gradle documentation on how to do integration tests for all the details.
We use in our java project jacoco with the gradle-plugin to calculate the coverage.
The problem is we put our classes which were generated from an XML in an extra project and resolved it as a dependency. We want the codecoverage of these model classes too to analyze it. To check if we used all setter methods of the datacontainers in our mapper classes. Do the code coverage in the model project is not an option.
Currently jacoco only shows in the report (html/xml/csv) only our classes which is in the main project but not the classes of external jars. The jacoco session contains the coverage data when I load it with eclipse or intellij.
buildscript {
...
dependencies {
...
classpath 'externalpackage:externalpackage-model'
...
}
}
compile('externalpackage:externalpackage-model:0.0.8')
testCompile('externalpackage:externalpackage-model:tests#jar')
testCompile('externalpackage:externalpackage-model:0.0.8:sources#jar')
jacoco {
toolVersion = "0.7.6.201602180812"
reportsDir = file("$buildDir/customJacocoReportDir")
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled true
html.enabled true
html.destination "${buildDir}/jacocoHtml"
}
additionalSourceDirs files('externalpackage:externalpagage:0.0.8:sources#jar')
//Doesn't work either
//additionalSourceDirs files('C:/Users/sero/Downloads/test/externalpackage-0.0.8-sources')
//additionalSourceDirs = files('C:/Users/sero/Downloads/test/externalpackage-0.0.8-sources/de/mycompany/.../MyModelClasses.java')
}
The jar source package is like this:
(root)/de/mycompany/.../MyModelClasses.java
Maybe someone has an idea
Found it by myself. Problem was, you need to specify the path the the classes too.
I unzipped the jars into the build folder and added additionalClassDirs and additionalSourceDirs to the report job.
This is the buildfile.
configurations {
externalClasses
externalSources
}
dependencies {
externalClasses "externalpackage:externalpackage-model:0.0.8#jar"
externalSources "externalpackage:externalpackage-model:0.0.8:sources#jar"
...
}
buildscript {
...
dependencies {
...
classpath 'externalpackage:externalpackage-model'
...
}
}
compile('externalpackage:externalpackage-model:0.0.8')
testCompile('externalpackage:externalpackage-model:tests#jar')
testCompile('externalpackage:externalpackage-model:0.0.8:sources#jar')
jacoco {
toolVersion = "0.7.6.201602180812"
reportsDir = file("$buildDir/customJacocoReportDir")
}
task unzipExternalModel(type: Copy){
from zipTree(configurations.externalSources.files.first())
into "$buildDir/tmp/externalSources"
from zipTree(configurations.externalClasses.files.first())
into "$buildDir/tmp/externalClasses"
}
jacocoTestReport {
dependsOn unzipExternalModel
reports {
xml.enabled true
csv.enabled true
html.enabled true
html.destination "${buildDir}/jacocoHtml"
}
additionalSourceDirs = files("$buildDir/tmp/externalSources")
additionalClassDirs = files("$buildDir/tmp/externalClasses")
}
Just for the record, using 7.1.1, this code (inpired on the Vincent's) works:
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
jacoco {
includes = ["com.mycompany.**"]
includeNoLocationClasses true
}
}
task unzipLibrariesJar(type: Copy){
into "$buildDir/tmp/libClasses"
from {
configurations.runtimeClasspath
.filter { it.path.contains("mycompany") }
.collect {zipTree(it) }
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
task unzipLibrariesSrc(type: Copy){
into "$buildDir/tmp/libSources"
from {
configurations.runtimeClasspath
.filter { it.path.contains("mycompany") && new File(it.getPath().replace(".jar", "-sources.jar")).exists() }
.collect { new File(it.getPath().replace(".jar", "-sources.jar")) }
.collect { zipTree(it) }
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
jacocoTestReport {
dependsOn test
dependsOn unzipLibrariesJar
dependsOn unzipLibrariesSrc
reports {
html.enabled true
}
additionalClassDirs.from = files("$buildDir/tmp/libClasses")
additionalSourceDirs.from = files("$buildDir/tmp/libSources")
}
Note that, I am only interested on the logs from all classes of "com.mycompany" package. You should change this according to your requirements.
I keep having very often the below error when running jUnit tests from Intellij command line with the following command: gradlew clean test aggregate -Dtags="domain:SmokeTests"
The page object class de.telekom.commtech.bart.pages.common.TelekomLandingPageObject looks dodgy: Failed to instantiate page (net.thucydides.core.webdriver.UnsupportedDriverException: Could not instantiate class org.openqa.selenium.firefox.FirefoxDriver) de.telekom.commtech.bart.steps.AbstractScenarioSteps.getTelekomLandingPageObject(AbstractScenarioSteps.java :52) de.telekom.commtech.bart.steps.inbox.AuthNavigationSteps.landingPageShouldAppear(AuthNavigationSteps.java :245) de.telekom.commtech.bart.testcases.BaseTest.login(BaseTest.java :447) de.telekom.commtech.bart.testcases.adressbook.lefthandnavigation.AdressBookContactsGroupTestCase.setup(AdressBookContactsGroupTestCase.java :46)
I use latest version of Serenity Bdd (1.1.42) and Firefox 47.0.2
If I run individual tests with Run Configuration, I don't get that error.
I tried downgrading the Firefox version to 45.0, but it acts the same.
What else can I try?
EDIT: The build.gradle file looks like this:
repositories {
mavenLocal()
maven {
name "bart"
credentials {
username nexusUser
password nexusPassword
}
url nexusBartRepoUrl
}
maven {
name "Testchameleon"
url "https://admin.testChameleon.com/artifactory/libs-release-local"
}
jcenter()
}
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath("net.serenity-bdd:serenity-gradle-plugin:1.1.42")
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.2'
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.8'
}
}
group = 'de.telekom.bart'
description = 'Bart Test Framework'
apply plugin: 'org.asciidoctor.convert'
apply plugin: 'java'
apply plugin: 'net.serenity-bdd.aggregator'
tasks.withType(JavaCompile) {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
options.deprecation = true
options.encoding = 'UTF-8'
options.compilerArgs << "-Xlint:unchecked"
}
dependencies {
compile('de.telekom.bart:bart-account-manager:2.0.12')
compile('net.serenity-bdd:serenity-core:1.1.42')
compile('org.slf4j:slf4j-api:1.7.7')
compile('org.slf4j:log4j-over-slf4j:1.7.7')
compile('org.slf4j:jul-to-slf4j:1.7.7')
compile('org.slf4j:jcl-over-slf4j:1.7.7')
compile('ch.qos.logback:logback-classic:1.1.3')
compile('de.testbirds.tech:testcase-api:0.3.20')
compile('org.mnode.ical4j:ical4j:1.0.7')
compile('org.apache.commons:commons-lang3:3.1')
testCompile('net.serenity-bdd:serenity-junit:1.1.42')
testCompile('org.reflections:reflections:0.9.8')
testCompile('junit:junit:4.12')
testCompile('org.assertj:assertj-core:1.7.0')
}
gradle.startParameter.continueOnFailure = true
test {
maxParallelForks = Runtime.runtime.availableProcessors()
if (System.properties['https.proxyHost']) {
systemProperty 'https.proxyHost', System.properties['https.proxyHost']
systemProperty 'https.proxyPort', System.properties['https.proxyPort']
systemProperty 'https.nonProxyHosts', System.properties['https.nonProxyHosts']
}
if (System.properties['http.proxyHost']) {
systemProperty 'http.proxyHost', System.properties['http.proxyHost']
systemProperty 'http.proxyPort', System.properties['http.proxyPort']
systemProperty 'http.nonProxyHosts', System.properties['http.nonProxyHosts']
}
if (System.properties['tags']) {
systemProperty 'tags', System.properties['tags']
}
System.properties.each { key, value ->
if (key.startsWith('serenity') || key.startsWith('webdriver') || key.startsWith('bart') ||(key.startsWith('test'))) {
systemProperty key, value
}
}
testLogging {
showStandardStreams = true
}
/* Pass all system properties: */
systemProperties System.getProperties()
beforeTest { descriptor ->
logger.lifecycle("Running test: ${descriptor}")
}
}
asciidoctor {
//backends = ['html5', 'pdf']
backends = ['html5']
sources {
include 'index.adoc'
}
}
task copyDocs(type: Copy, dependsOn: 'asciidoctor') {
from asciidoctor.outputDir.canonicalPath
into '/data/www/htdocs/bart-docs'
}
task wrapper(type: Wrapper) {
gradleVersion = '3.1'
}