Integration tests with Gradle Kotlin DSL - gradle

I'm using this blog post to configure integration tests for a Spring Boot project, but I'm pretty stuck on declaring the source sets. I also found this post on StackOverflow, but I think I'm a bit further already.
My project structure is
project
|_ src
|_ main
| |_ kotlin
| |_ resources
|_ testIntegration
| |_ kotlin
| |_ resources
|_ test
| |_ kotlin
| |_ resources
|_ build.gradle.kts
|_ ... other files
And build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
idea
kotlin("jvm")
id("org.springframework.boot") version "2.0.5.RELEASE"
id("org.jetbrains.kotlin.plugin.spring") version "1.2.71"
}
fun DependencyHandlerScope.springBoot(module: String) = this.compile("org.springframework.boot:spring-boot-$module:2.0.5.RELEASE")
fun DependencyHandlerScope.springBootStarter(module: String) = this.springBoot("starter-$module")
dependencies {
springBoot("devtools")
springBootStarter("batch")
springBootStarter("... spring boot dependencies")
compile("... more dependencies")
testCompile("... more test dependencies")
}
val test by tasks.getting(Test::class) {
useJUnitPlatform { }
}
kotlin {
sourceSets {
val integrationTest by creating {
kotlin.srcDir("src/testIntegration/kotlin")
resources.srcDir("src/testIntegration/resources")
}
}
}
val integrationTestCompile by configurations.creating {
extendsFrom(configurations["testCompile"])
}
val integrationTestRuntime by configurations.creating {
extendsFrom(configurations["testRuntime"])
}
val testIntegration by tasks.creating(Test::class) {
group = "verification"
testClassesDirs = kotlin.sourceSets["integrationTest"].kotlin
}
idea {
module {
testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].kotlin.srcDirs)
testSourceDirs.addAll(kotlin.sourceSets["integrationTest"].resources.srcDirs)
}
}
I think I'm pretty much in the right direction. At least it doesn't throw an exception any more :)
When I run the testIntegration task, I get the following output:
Testing started at 12:08 ...
12:08:49: Executing task 'testIntegration'...
> Task :project:compileKotlin UP-TO-DATE
> Task :project:compileJava NO-SOURCE
> Task :project:processResources UP-TO-DATE
> Task :project:classes UP-TO-DATE
> Task :project:compileTestKotlin UP-TO-DATE
> Task :project:compileTestJava NO-SOURCE
> Task :project:processTestResources UP-TO-DATE
> Task :project:testClasses UP-TO-DATE
> Task :project:testIntegration
BUILD SUCCESSFUL in 2s
5 actionable tasks: 1 executed, 4 up-to-date
12:08:51: Task execution finished 'testIntegration'.
Also, IntelliJ doesn't recognise the testIntegration directories as Kotlin packages.

I was finally able to figure it out thanks to some help on the Kotlin Slack channel. First of all I had to upgrade to Gradle version 4.10.2.
For more info have a look at these two pages from Gradle:
https://docs.gradle.org/release-nightly/userguide/organizing_gradle_projects.html#sec:separate_test_type_source_files
https://docs.gradle.org/release-nightly/userguide/organizing_gradle_projects.html#sec:separate_test_type_source_files
Then I just had to create the sourceSets for the integrationTests
sourceSets {
create("integrationTest") {
kotlin.srcDir("src/integrationTest/kotlin")
resources.srcDir("src/integrationTest/resources")
compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
}
}
This would work just fine for Java, but since I'm working with Kotlin I had to add an extra withConvention wrapper
sourceSets {
create("integrationTest") {
withConvention(KotlinSourceSet::class) {
kotlin.srcDir("src/integrationTest/kotlin")
resources.srcDir("src/integrationTest/resources")
compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
}
}
}
In the docs they only put runtimeClasspath += output + compileClasspath, but I added sourceSets["test"].runtimeClasspath so I can directly use the test dependencies instead of declaring new dependencies for the integrationTest task.
Once the sourceSets were created it was a matter of declaring a new task
task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}
After this the tests still didn't run, but that was because I'm using JUnit4. So I just had to add useJUnitPlatform() which makes this the final code
task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
useJUnitPlatform()
}

I didnt like the use of withConvention and how the kotlin src dir was set. So after check out both gradle docs here and here, I came up with this:
sourceSets {
create("integrationTest") {
kotlin {
compileClasspath += main.get().output + configurations.testRuntimeClasspath
runtimeClasspath += output + compileClasspath
}
}
}
val integrationTest = task<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}
tasks.check {
dependsOn(integrationTest)
}
I preferr the less verbose style when using kotlin { and the use of variable for the new integrationTestTask.

As of Gradle 5.2.1 see https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
sourceSets {
create("intTest") {
compileClasspath += sourceSets.main.get().output
runtimeClasspath += sourceSets.main.get().output
}
}
val intTestImplementation by configurations.getting {
extendsFrom(configurations.testImplementation.get())
}
configurations["intTestRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
dependencies {
intTestImplementation("junit:junit:4.12")
}
val integrationTest = task<Test>("integrationTest") {
description = "Runs integration tests."
group = "verification"
testClassesDirs = sourceSets["intTest"].output.classesDirs
classpath = sourceSets["intTest"].runtimeClasspath
shouldRunAfter("test")
}
tasks.check { dependsOn(integrationTest) }

Here is git repo that you can refer to: enter link description here
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins {
application
kotlin("jvm") version "1.3.72"
id("com.diffplug.gradle.spotless") version "3.24.2"
id("org.jmailen.kotlinter") version "1.26.0"
checkstyle
}
version = "1.0.2"
group = "org.sample"
application {
mainClass.set("org.sample.MainKt")
}
repositories {
mavenCentral()
jcenter()
}
tasks.checkstyleMain { group = "verification" }
tasks.checkstyleTest { group = "verification" }
spotless {
kotlin {
ktlint()
}
kotlinGradle {
target(fileTree(projectDir).apply {
include("*.gradle.kts")
} + fileTree("src").apply {
include("**/*.gradle.kts")
})
ktlint()
}
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
lifecycle {
events = mutableSetOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
exceptionFormat = TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
showStandardStreams = true
}
info.events = lifecycle.events
info.exceptionFormat = lifecycle.exceptionFormat
}
val failedTests = mutableListOf<TestDescriptor>()
val skippedTests = mutableListOf<TestDescriptor>()
addTestListener(object : TestListener {
override fun beforeSuite(suite: TestDescriptor) {}
override fun beforeTest(testDescriptor: TestDescriptor) {}
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
when (result.resultType) {
TestResult.ResultType.FAILURE -> failedTests.add(testDescriptor)
TestResult.ResultType.SKIPPED -> skippedTests.add(testDescriptor)
else -> Unit
}
}
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
if (suite.parent == null) { // root suite
logger.lifecycle("----")
logger.lifecycle("Test result: ${result.resultType}")
logger.lifecycle(
"Test summary: ${result.testCount} tests, " +
"${result.successfulTestCount} succeeded, " +
"${result.failedTestCount} failed, " +
"${result.skippedTestCount} skipped")
failedTests.takeIf { it.isNotEmpty() }?.prefixedSummary("\tFailed Tests")
skippedTests.takeIf { it.isNotEmpty() }?.prefixedSummary("\tSkipped Tests:")
}
}
private infix fun List<TestDescriptor>.prefixedSummary(subject: String) {
logger.lifecycle(subject)
forEach { test -> logger.lifecycle("\t\t${test.displayName()}") }
}
private fun TestDescriptor.displayName() = parent?.let { "${it.name} - $name" } ?: "$name"
})
}
dependencies {
implementation(kotlin("stdlib"))
implementation("com.sparkjava:spark-core:2.5.4")
implementation("org.slf4j:slf4j-simple:1.7.30")
testImplementation("com.squareup.okhttp:okhttp:2.5.0")
testImplementation("io.kotest:kotest-runner-junit5-jvm:4.0.5")
testImplementation("io.kotest:kotest-assertions-core-jvm:4.0.5") // for kotest core jvm assertions
testImplementation("io.kotest:kotest-property-jvm:4.0.5")
}
sourceSets {
create("integTest") {
kotlin {
compileClasspath += main.get().output + configurations.testRuntimeClasspath
runtimeClasspath += output + compileClasspath
}
}
}
val integTest = task<Test>("integTest") {
description = "Runs the integTest tests"
group = "verification"
testClassesDirs = sourceSets["integTest"].output.classesDirs
classpath = sourceSets["integTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}
tasks.check {
dependsOn(integTest)
}
sourceSets {
create("journeyTest") {
kotlin {
compileClasspath += main.get().output + configurations.testRuntimeClasspath
runtimeClasspath += output + compileClasspath
}
}
}
val journeyTest = task<Test>("journeyTest") {
description = "Runs the JourneyTest tests"
group = "verification"
testClassesDirs = sourceSets["journeyTest"].output.classesDirs
classpath = sourceSets["journeyTest"].runtimeClasspath
mustRunAfter(tasks["integTest"])
}
tasks.check {
dependsOn(journeyTest)
}
I hope this helps. :)

There is a dedicated Gradle feature called Declarative Test Suite that supports this case:
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
register("integrationTest", JvmTestSuite::class) {
dependencies {
implementation(project())
}
targets {
all {
testTask.configure {
shouldRunAfter(test)
}
}
}
}
}
}
More:
https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests

Related

Gradle Configuration for Kotlin Multiplatform Project in Java and Js

Seems all ok! But...
I have created a Kotlin Multiplatform Project in Js and Java. I worked on create the right tests for all target and the right configuration for the build. Seems all go right, i managed to create the build and set it in the right way. Today i have opened the project and it stop, the build complete successfull but test and java compilations don't be executed.
So how i can configure it?
With code and result all will be more clear
build.gradle.kts
import com.moowork.gradle.node.npm.NpmTask
import com.moowork.gradle.node.task.NodeTask
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50")
}
}
plugins {
kotlin("multiplatform") version "1.3.50"
id("com.moowork.node") version "1.3.1"
}
repositories {
mavenCentral()
jcenter()
}
group = "com.example"
version = "0.0.1"
kotlin {
jvm()
js()
jvm {
withJava()
}
js {
nodejs()
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
jvm {
compilations["main"].defaultSourceSet {
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
}
compilations["test"].defaultSourceSet {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
}
js {
sequenceOf("", "Test").forEach {
tasks.getByName<KotlinJsCompile>("compile${it}KotlinJs") {
kotlinOptions {
moduleKind = "umd"
noStdlib = true
metaInfo = true
}
}
}
compilations["main"].defaultSourceSet {
dependencies {
implementation(kotlin("stdlib-js"))
}
}
compilations["test"].defaultSourceSet {
dependencies {
implementation(kotlin("test-js"))
}
}
}
}
}
val compileKotlinJs = tasks.getByName("compileKotlinJs")
val compileTestKotlinJs = tasks.getByName("compileTestKotlinJs")
val libDir = "$buildDir/lib"
val compileOutput = compileKotlinJs.getOutputs().getFiles()
val testOutput = compileTestKotlinJs.getOutputs().getFiles()
val populateNodeModules = tasks.create<Copy>("populateNodeModules") {
afterEvaluate {
from(compileOutput)
from(testOutput)
configurations["testCompile"].forEach {
if (it.exists() && !it.isDirectory) {
from(zipTree(it.absolutePath).matching { include("*.js") })
}
}
for (sourceSet in kotlin.sourceSets) {
from(sourceSet.resources)
}
into("$buildDir/node_modules")
}
dependsOn("compileKotlinJs")
}
node {
download = true;
}
tasks.create<NpmTask> ("installJest") {
setArgs(setOf("install", "jest"))
}
tasks.create<NodeTask> ("runJest") {
setDependsOn(setOf("installJest", "populateNodeModules", "compileTestKotlinJs"))
setScript(file("node_modules/jest/bin/jest.js"))
setArgs(compileTestKotlinJs.outputs.files.toMutableList().map {projectDir.toURI().relativize(it.toURI())})
}
tasks.getByName("test").dependsOn("runJest")
Look how many task are skiped! and how build Dir is created
buid result
build dir
I use jest to test in js.
Thanks in advance for support me

How do I publish a second library from another sourceset in gradle?

I have this tlib sourceset
sourceSets {
val main by getting
val tlib by creating {
compileClasspath += main.output
runtimeClasspath += main.output
}
val test by getting {
compileClasspath += tlib.output
runtimeClasspath += tlib.output
}
}
configurations {
val tlibCompile by getting {
extendsFrom(configurations["implementation"])
}
}
I am imagining something like this, but this is not complete
publishing {
publications {
val tlibSourcesJar by tasks.registering(Jar::class) {
classifier = "sources"
from(sourceSets["tlib"].allSource)
}
register("mavenTLib", MavenPublication::class) {
from(components["tlib"])
artifact(tlibSourcesJar.get())
}
}
}
but I get
Could not create domain object 'mavenTLib' (MavenPublication)
> SoftwareComponentInternal with name 'tlib' not found.
How can I publish my test lib separately from my main lib?
this works to an extent but is probably not the best way to do it
sourceSets {
val main by getting
val tlib by creating {
compileClasspath += main.output
runtimeClasspath += main.output
}
val test by getting {
compileClasspath += tlib.output
runtimeClasspath += tlib.output
}
}
configurations {
val tlibCompile by getting {
extendsFrom(configurations["implementation"])
}
}
publishing {
publications {
val tlibJar by tasks.registering(Jar::class) {
from(sourceSets["tlib"].output)
}
val tlibSourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources")
from(sourceSets["tlib"].allSource)
}
register("mavenTLib", MavenPublication::class) {
artifactId = "phg-entity-tlib"
artifact(tlibJar.get())
artifact(tlibSourcesJar.get())
}
}
}
I have an example here, unfortunately it is written in Groovy, and I am not yet familiar with the Kotlin way of doing it.
Maybe it still helps:
https://github.com/thokari/gradle-workshop/blob/master/examples/09-multiple-artifacts/build.gradle
The most relevant part is probably this:
outputArchives.each { outputArchive ->
String logicalName = outputArchive.camelCase()
// Add archiving tasks.
// These could be anything with type AbstractArchiveTask (e.g. War, Zip).
task("${logicalName}Jar", type: Jar) { from configurations."${logicalName}Compile" }
task("${logicalName}SourceJar", type: Jar) { from sourceSets."${logicalName}".java }
// Configure the publishing extension added by the 'maven-publish' plugin.
// For every combination of publication and repository, a task with name
// publish<publicationName>PublicationTo<repositoryName>Repository is created.
// The task 'publish' is a shortcut, depending on each one of them.
publishing {
publications {
// Create a publication by calling its name and type.
"${logicalName}"(MavenPublication) {
// Override the artifact id, which defaults to the project name.
artifactId = outputArchive.dashSeparated()
// Publish the artifacts created by the archiving tasks.
artifact tasks."${logicalName}Jar"
artifact(tasks."${logicalName}SourceJar") { classifier 'source' }
}
}
}
}
I also never figured out how to make use of this SoftwareComponent concept. I solved this by calling the artifact method on the archiving tasks that I created, instead of using from(component), I would think this could also be done in Kotlin.

Xtext: Couldn't resolve reference to JvmType MyGeneratorModule

I am copying the structure of the example Xtext Web project for multiple dsl's using the Entities and StateMachine example. I am using Gradle as my build system. I have a class MyGeneratorModule in both of my grammar projects. In my workflow I reference it like this:
configuration = MyGeneratorModule {...}
I can run the workflow fine in each project, but when I try to perform a jettyRun from the web project I get this error:
Task :com.selinc.logic.program:generateXtextLanguage FAILED
0 [main] ERROR mf.mwe2.launch.runtime.Mwe2Launcher - [XtextLinkingDiagnostic: null:17 Couldn't resolve reference to JvmType 'MyGeneratorModule'.
Am i missing something in the workflow or gradle build? Here is a more complete example of my languages build.gradle file and workflow:
mwe2:
component = XtextGenerator {
configuration = MyGeneratorModule { // <- This is what is not resolving
project = StandardProjectConfig {
baseName = baseName
rootPath = rootPath
runtimeTest = {
enabled = true
}
web = {
enabled = true
root = "../myWebProject"
src = "../myWebProject/src/main/java"
srcGen = "../myWebProject/src/main/xtext-gen"
assets = "../myWebProject/src/main/webapp"
}
mavenLayout = true
}
code = {
encoding = "UTF-8"
lineDelimiter = "\r\n"
fileHeader = "/*\n * generated by Xtext \${version}\n */"
}
}
cleaner = {
exclude = "MyOtherLanguageWebModule.java"
}
language = StandardLanguage {
name = "MyLang"
fileExtensions = "lang"
serializer = {
generateStub = false
}
webSupport = {
generateHtmlExample = true
framework = "CODEMIRROR"
generateJsHighlighting = false
generateServlet = false
generateWebXml=true
}
junitSupport = {
junitVersion = "5"
}
}
}
build.gradle:
dependencies {
testCompile "org.junit.jupiter:junit-jupiter-api:5.1.0"
testRuntime "org.junit.jupiter:junit-jupiter-engine:5.1.0"
testCompile "org.eclipse.xtext:org.eclipse.xtext.testing:${xtextVersion}"
compile project(':myOtherLang')
compile project(':myXCoreModel')
compile project(":util")
compile group: 'org.eclipse.xtext', name: 'org.eclipse.xtext.ecore', version: '2.15.0'
compile "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}"
}
sourceSets {
mwe2 {}
}
configurations {
mwe2 {
extendsFrom compile
}
mwe2Compile.extendsFrom mainCompile
mwe2Runtime.extendsFrom mainRuntime
}
sourceSets.mwe2.java.srcDir 'generator'
dependencies {
mwe2Compile "org.eclipse.emf:org.eclipse.emf.mwe2.launch:2.9.1.201705291010"
mwe2Compile "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}"
mwe2Compile "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
mwe2Compile "org.eclipse.xtext:xtext-antlr-generator:[2.1.1, 3)"
//added for xcore support
mwe2Compile 'org.eclipse.emf:org.eclipse.emf.ecore.xcore:1.3.1'
mwe2Compile 'org.eclipse.emf:org.eclipse.emf.codegen.ecore.xtext:+'
}
task generateXtextLanguage(type: JavaExec) {
main = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher'
classpath = project.sourceSets.mwe2.runtimeClasspath
inputs.file "path/GenerateMyLang.mwe2"
inputs.file "path/MyLang.xtext"
outputs.dir "src-gen"
args += "path/GenerateMyLang.mwe2"
args += "-p"
args += "rootPath=/${projectDir}/.."
}
test {
useJUnitPlatform()
}
generateXtext.dependsOn(generateXtextLanguage)
clean.dependsOn(cleanGenerateXtextLanguage)
eclipse.classpath.plusConfigurations += [configurations.mwe2]
i have doubts if this will work. the code you copy from does not generate an xtext language
you should move custom modules to a separate gradle project and thus compile it separately. alernatively you can experiment with gradle buildSrc/separate source folder code
(am not sure if this works for this usecase)
dependencies {
compile "org.eclipse.xtext:org.eclipse.xtext:${xtextVersion}"
compile "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}"
}
sourceSets {
mwe2 {}
}
configurations {
mwe2 {
extendsFrom compile
}
mwe2Compile.extendsFrom mainCompile
mwe2Runtime.extendsFrom mainRuntime
}
sourceSets.mwe2.java.srcDir 'generator'
dependencies {
mwe2Compile "org.eclipse.emf:org.eclipse.emf.mwe2.launch:2.9.1.201705291010"
mwe2Compile "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}"
mwe2Compile "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
mwe2Compile "org.eclipse.xtext:xtext-antlr-generator:[2.1.1, 3)"
}
task generateXtextLanguage(type: JavaExec) {
main = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher'
classpath = project.sourceSets.mwe2.runtimeClasspath
inputs.file "src/org/xtext/example/mydsl/GenerateMyDsl.mwe2"
inputs.file "src/org/xtext/example/mydsl/MyDsl.xtext"
outputs.dir "src-gen"
args += "src/org/xtext/example/mydsl/GenerateMyDsl.mwe2"
args += "-p"
args += "rootPath=/${projectDir}/.."
}
generateXtext.dependsOn(generateXtextLanguage)
clean.dependsOn(cleanGenerateXtextLanguage)
eclipse.classpath.plusConfigurations += [configurations.mwe2]

Could not find method intTestImplementation() for arguments [org.hibernate:hibernate:5.3.7.FINAL] on object of type DefaultDependencyHandler

I am trying to configure the Integration tests in Gradle 5.0.
I am seeing error as
Could not find method intTestImplementation() for arguments [org.hibernate:hibernate:5.3.7.FINAL] on object of type DefaultDependencyHandler.
I can see the intTestImplementation when I say gradle dependencies
I am trying to add one dependency
intTestImplementation 'org.hibernate:hibernate:5.3.7.FINAL'
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.intTest.output.classesDirs
classpath = sourceSets.intTest.runtimeClasspath
shouldRunAfter test
}
sourceSets {
intTest {
java.srcDir file('src/integrationTest/java')
resources.srcDir file('src/integrationTest/resources') // to add the resources
}
}
You could try one of these two options and see if some of them works for you:
a) your custom sourceSets declared in this way:
sourceSets {
intTest {
java {
srcDirs = ['src/integrationTest/java']
}
resources {
srcDirs = ['src/integrationTest/resources']
}
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath + sourceSets.test.compileClasspath
runtimeClasspath += sourceSets.main.output + sourceSets.main.runtimeClasspath + sourceSets.test.runtimeClasspath
}
}
In this case you would be declaring your dependencies for integration tests in the same way as the dependencies for tests. Just like this:
testImplementation 'org.hibernate:hibernate:5.3.7.FINAL'
b) intTestImplementation must be declared after your custom sourceSets:
sourceSets {
intTest {
java {
srcDirs = ['src/integrationTest/java']
}
resources {
srcDirs = ['src/integrationTest/resources']
}
}
}
dependencies {
intTestImplementation 'org.hibernate:hibernate:5.3.7.FINAL'
}
I got similar message because I had my sourceSets defined after dependencies

How to create sourceset in custom plugin

I'm writing custom plugin which should create number of sourcesets depends on plugin extension.
How can I do it in apply method?
Here's my code snippets (both don't work), labels - list from extension:
1.
project.sourceSets {
labels.each { info ->
"${info.lower}Src" {
java.srcDirs = ['src'] + info.srcPostfix.collect { postfix -> "src_custom/${postfix}" }
}
}
main { java.srcDirs = ['src'] + labels.collect { info -> "src_custom/${info.lower}" } }
test { java.srcDirs = ['test'] + labels.collect { info -> "test_custom/${info.lower}" } }
}
2.
labels.each { info ->
SourceSet modelSrc = project.sourceSets.create("${info.lower}Src")
modelSrc.getJava().setSrcDirs(['src'] + info.srcPostfix.collect { postfix -> "src_custom/${postfix}" })
}
SourceSetContainer sourceSets = project.convention.getPlugin(JavaPluginConvention).sourceSets
SourceSet mainSourceSet = sourceSets.getByName(MAIN_SOURCE_SET_NAME)
mainSourceSet.getJava().setSrcDirs(['src'] + labels.collect { info -> "src_custom/${info.lower}" })
SourceSet testSourceSet = sourceSets.getByName(TEST_SOURCE_SET_NAME)
testSourceSet.getJava().setSrcDirs(['test'] + labels.collect { info -> "test_custom/${info.lower}" })
I know this is old, but here's what I ran into. I needed to create a plugin that would create a sourceSet. What I had before was this in my build.gradle
sourceSets {
myNewSet {
groovy.srcDir file("${project.myNewSet_src}")
resources.srcDir file("${project.myNewSet_resources}")
}
}
So when I created my plugin, in the apply method, I had this:
project.getSourceSets().create("myNewSet", {
groovy.srcDir new File("${project.getProjectDir()}/${project.myNewSet_src}")
resources.srcDir new File("${project.getProjectDir()}/${project.myNewSet_resources}")
});
Hope this helps someone.
Here is an example what does it look like in Kotlin Gradle DSL, configuring Spring Boot's BootRun task project-wide in multiproject build:
tasks {
withType<BootRun> {
val createGitRevisionReport: GitRevisionReportTask by this#tasks
dependsOn(createGitRevisionReport)
val sourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets
val additionalSourceSet = sourceSets.create("bootRunAdditionalSourceSet") {
resources.srcDir(createGitRevisionReport.gitRevisionReportDir)
}
sourceResources(additionalSourceSet)
}
}

Resources