Kotlin Add Integration Tests Module - gradle

I am trying to add another module to my Kotlin project specifically for integration tests - living alongside the standard test module creating by the kotlin plugin. Here is my current configuration to add the sourceset:
sourceSets {
testIntegration {
java.srcDir 'src/testIntegration/java'
kotlin.srcDir 'src/testIntegration/kotlin'
resources.srcDir 'src/testIntegration/resources'
compileClasspath += main.output
runtimeClasspath += main.output
}
}
configurations {
provided
testCompile.extendsFrom provided
testIntegrationCompile.extendsFrom testCompile
testIntegrationRuntime.extendsFrom testRuntime
}
task testIntegration(type: Test) {
testClassesDirs = sourceSets.testIntegration.output.classesDirs
classpath = sourceSets.testIntegration.runtimeClasspath
}
This seems to work, however IntelliJ does not pick up the new source set as a test module. I can manually mark it, but it resets every time Gradle runs. This also means that Intellij fills in the Output Path and not the Test Output Path fields in the project structure settings.
To fix that the below configuration works:
apply plugin: 'idea'
idea {
module {
testSourceDirs += project.sourceSets.testIntegration.java.srcDirs
testSourceDirs += project.sourceSets.testIntegration.kotlin.srcDirs
testSourceDirs += project.sourceSets.testIntegration.resources.srcDirs
}
}
However, this seems to instruct IntelliJ that the Test Output Path is \out\test\classes which is the same as the standard 'test' module and causes conflict issues. I want it to keep the output path as the original \out\testIntegration\classes which would have otherwise been used.
Is there any way to instruct IntelliJ to pick up this new test source set correctly and fill in the right output path?

If you'd like to configure the idea gradle plugin with your custom test sourceSets in a kotlin gradle build script you can do it like that:
val testIntegrationSrcDirName = "testIntegration"
sourceSets {
...
create(testIntegrationSrcDirName) {
compileClasspath += sourceSets.main.get().output + sourceSets.test.get().output // take also unit test source and resources
runtimeClasspath += sourceSets.main.get().output + sourceSets.test.get().output // take also unit test source and resources
}
}
...
idea {
module {
testSourceDirs = testSourceDirs + sourceSets[testIntegrationSrcDirName].allSource.srcDirs
}
}
val testIntegrationImplementation: Configuration by configurations.getting {
extendsFrom(configurations.implementation.get())
}
configurations["${testIntegrationSrcDirName}RuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
...

Related

Include multiple sourcesets in the Jacoco's jacocoTestReport.xml file

I have a custom sourceSet defined in a Gradle based project, like this:
sourceSets {
componentTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/componentTest/java')
}
}
}
configurations {
componentTestImplementation.extendsFrom testImplementation
}
task componentTest(type: Test) {
dependsOn assemble
testClassesDirs = sourceSets.componentTest.output.classesDirs
classpath = sourceSets.componentTest.runtimeClasspath
outputs.upToDateWhen { false }
testLogging.showStandardStreams = true
mustRunAfter(test)
}
check.dependsOn(componentTest)
The sourceSet contains Cucumber features.
When running Jacoco, the generated jacocoTestReport.xml file doesn't seem to include the coverage generated by the Cucumber tests.
Here is the Jacoco configuration:
jacocoTestReport {
executionData(
file("${project.buildDir}/jacoco/test.exec"),
file("${project.buildDir}/jacoco/componentTest.exec"),
)
}
Is there anything I could do to get the same coverage in the xml file as I get in the exec files?
After further experiments it turns out the xml file includes the coverage from the componentTest sourceSet.
I asked this question because the coverage was not reflected correctly in SonarQube - I could not see the Cucumber tests from the componentTest in SonarQube. But it seems to me now, that the actual coverage values align with what the Jacoco report shows. I just had to exclude the same source classes in SonarQube as in Jacoco.

Spring cloud contracts plugin change sourceset

I've started using Spring Cloud Contracts ('2.0.2.RELEASE') in my project and I have the following structure
src
|
-- main
-- test
-- integrationTest
-- contractTest
When I put my contracts and my base test class in test it was running fine. I want to move the contract tests that I have written into a separate sourceset, the contractTest sources. However, this will not work as the plugin generateContractTests task will still look in the test sourceset when trying to run.
I have made the following changes to my Gradle file
task contractTest(type: Test) {
description = 'Runs contract tests.'
group = 'verification'
testClassesDirs = sourceSets.contractTest.output.classesDirs
classpath = sourceSets.contractTest.runtimeClasspath
shouldRunAfter integrationTest
}
configurations {
contractTestImplementation.extendsFrom implementation
contractTestRuntimeOnly.extendsFrom runtimeOnly
}
sourceSets {
contractTest {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
contracts {
// testFramework = 'JUNIT5'
packageWithBaseClasses = 'com.test.testapi.contracts'
contractsDslDir = new File("${project.rootDir}/src/contractTest/resources/contracts/")
}
contractTestImplementation 'org.codehaus.groovy:groovy-all:2.4.6'
contractTestImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
contractTestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api'
contractTestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine'
I think I need to set the contract plugin property contractDependency, however, I am not sure and can't find an example to get the plugin to work with this different sourceset
TLDR; I want to be able to run my contract tests in a different folder
UPDATE - I am not sure but I think that it is not possible as in the Gradle plugin in the "GenerateServerTestsTask.groovy" file has the following which would appear to signify that the sourceSet is hardcoded to test throughout the code
project.sourceSets.test.groovy {
project.logger.
info("Registering ${getConfigProperties().generatedTestSourcesDir} as test source directory")
srcDir getConfigProperties().getGeneratedTestSourcesDir()
}
For future reference, I was able to get it working by creating a custom task to deregister the generated sources from the test sourceset so that they wouldn't be compiled by compileTestJava and could be run via my own contractTests task.
sourceSets {
contractTest {
java {
compileClasspath += sourceSets.main.output + sourceSets.test.output
runtimeClasspath += sourceSets.main.output + sourceSets.test.output
srcDir file('src/contractTest/java')
srcDirs += file("${buildDir}/generated-contract-sources/")
}
resources.srcDir file('src/contractTest/resources')
}
}
task deregisterContractTestSources() {
doLast {
project.sourceSets.test.java {
project.logger.info('Removing any *Spec classes from the test sources')
exclude '**/*Spec*'
}
}
}
compileTestJava.dependsOn deregisterContractTestSources
task contractTests(type: Test) {
description = 'Runs contract tests'
group = 'verification'
testClassesDirs = sourceSets.contractTest.output.classesDirs
classpath = sourceSets.contractTest.runtimeClasspath
}
contracts {
baseClassForTests = 'com'
generatedTestSourcesDir = file("${buildDir}/generated-contract-sources")
generatedTestResourcesDir = file("${buildDir}/generated-contract-resources/")
testFramework = "JUNIT5"
contractsDslDir = new File("${projectDir}/src/contractTest/resources/contracts/")
nameSuffixForTests = 'Spec'
basePackageForTests = 'com'
}

Spock test in gradle could not be configured in a separate sourceSet

I have been trying to configure spock in the gradle project. So with the following configuration, it works out.
apply plugin: 'groovy'
My test cases are in the folder src/test/groovy. This works fine.I am able to run the test case.
However , I want to separate the integration tests into a separate folder structure - src/itest/groovy.
For this I added the following:
sourceSets {
itest {
srcDir file('src/itest/groovy')
}
resourceDir ..
compileClassPath ..
}
configurations {
itestCompile.extendsfrom testCompile
}
I am not able to copy the entire code here because of org restrictions. But I did try what all variations I could get online and it did not work!!
I always got the error:
The task compileItestGroovy was not found in the project.
I did some research and this task is added by the groovy plugin by default. Still the task could not be found and my build is in limbo. It would be great if you could help me up with this.
P.S This project also has other plugins such as java as the source code is in java.
Command to run - ./gradlew clean build
Gradle version - 2.2.1
I tried similar set up on my home pc with gradle version 3.5 and it works fine.
Given the following build.gradle file:
apply plugin: 'groovy'
repositories {
jcenter()
}
sourceSets {
integration {
groovy {
compileClasspath += main.output
runtimeClasspath += main.output
srcDirs = ['src/integration/groovy']
}
resources.srcDir file('src/integration/resources')
}
}
configurations {
// By default, integration tests have the same dependencies as standard tests
integrationCompile.extendsFrom testCompile
integrationRuntime.extendsFrom testRuntime
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.12'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
// This is only available for the integration tests
integrationCompile 'com.github.ben-manes.caffeine:caffeine:2.5.5'
}
tasks.create('integrationTest', Test) {
dependsOn 'compileIntegrationGroovy'
group = 'Verification'
description = 'Runs the integration tests'
// GRADLE 2.2
testClassesDir = sourceSets.integration.output.classesDir
// GRADLE 3.5
// testClassesDirs = sourceSets.integration.output.classesDirs
classpath = sourceSets.integration.runtimeClasspath
}
tasks.findByName('check').dependsOn 'integrationTest'
You should be able to stick integration tests inside src/integration/groovy and ./gradlew check will run both the standard tests, AND the integration tests

Add additional source set to Gretty classpath

My project contains a jar and a war module. The jar module contains to source sets main and generated.
My jar module gradle.build defines the source sets as listed below:
sourceSets {
generated
main {
compileClasspath += sourceSets.generated.output // adds the sourceSet to the compileClassPath
runtimeClasspath += sourceSets.generated.output // adds the sourceSet to the runtimeClasspath
}
}
and places the output of both source sets into the jar.
jar {
from sourceSets.generated.output
from sourceSets.main.output
}
Within my war module I'd like to use Gretty to run it within the build. The build.gradle file looks like this.
apply plugin: 'war'
apply from: "${rootDir}/gradle/gretty.gradle"
gretty {
// supported values:
// 'jetty7', 'jetty8', 'jetty9', 'tomcat7', 'tomcat8'
servletContainer = 'tomcat8'
httpPort = 8081
contextPath = '/wbc'
realm 'wbc-realm'
realmConfigFile 'tomcat-users.xml'
}
dependencies {
compile project(':interfaces')
compile "org.atmosphere:atmosphere-runtime:${atmosphereVersion}"
compile "org.springframework:spring-web:${springVersion}"
compile "javax.servlet:javax.servlet-api:${servletVersion}"
runtime "org.slf4j:slf4j-log4j12:${slf4jVersion}"
runtime "log4j:log4j:1.2.17"
}
Whenever I start Gretty using gradle --daemon clean appRun Gretty fails to start up Tomcat due to a ClassNotFoundException. That class is located in the generated source set of my jar module. How can I tell gretty to add it to the classpath?
Try adding the output directories of generated to gretty classPath:
gretty {
...
sourceSets.generated.output.each { classPath it }
}

Gradle dependency on source set

I have a project with 3 source sets. One common, and two dependent on it.
sourceSets {
common {}
api {
compileClasspath += common.output
runtimeClasspath += common.output
}
main {
compileClasspath += common.output
runtimeClasspath += common.output
}
}
Also i have some dependencies.
dependencies {
...
commonCompile 'com.google.guava:guava:18.0'
commonCompile 'io.netty:netty-all:4.0.23.Final'
...
compile 'io.dropwizard.metrics:metrics-core:3.1.0'
compile 'io.dropwizard.metrics:metrics-healthchecks:3.1.0'
...
}
Also i have a different project and want to add dependency on api source set from first project.
How can i do such thing?
Thanks.

Resources