I’ve been through the gradle manual and looked at the java multi-project example and I haven’t been able to figure out how to do what I’m imagining, or more importantly whether this is even a smart way to go about this.
My structure looks like this
app/
build.gradle
settings.gradle
src/main/{java,resources}
src/test/{java,resources}
acceptance/
build.gradle
src/main/test/{java,resources}
app/src/test
is where we’re placing JUnit/unit tests and app/acceptance/src/test
is where we’re placing cucumber acceptance tests.
I’ve opted for a sub-project as we want classpath isolation, the acceptance
project will only make HTTP requests against the an instance of the service from the top level project.
Note: I could use a Java source set but then we hit an issue in IntelliJ where it has only “main” and “test” classpaths and I want a third. I can’t budge on using IntelliJ because of work so I want to make the IDE experience as smooth as possible. A sub-project/module works well in IDEA.
My problem comes alongside a task defined in app/acceptance/build.gradle
named cucumber
. This task invokes Cucumber CLI via the javaexec
tasks and this is fine. I would like the behaviour where if cucumber
is invoked from the app/
dir, a doFirst
and doLast
is invoked to setup and teardown an instance of the app/
.
I can run the app easily with gradle run
(or gradle runShadow
) – but I cannot get gradle to co-ordinate doing some setup and teardown in the root project when the cucumber
task is called in the acceptance sub-project.
I attempted to put the following in app/build.gradle
:
project(':acceptance') {
cucumber {
dependsOn test
doFirst {
println 'BEFORE ACCEPTANCE TESTS!'
}
doLast {
println 'AFTER ACCEPTANCE TESTS!'
}
}
}
But I get the following error:
Could not find method cucumber() for arguments [build_fk50yayrqj9dxaqt2zuh3qia$_run_closure9_closure12@1665fa54] on root project 'app'.
The cucumber
task is defined as follows (in app/acceptance/build.gradle
):
task cucumber() {
dependsOn assemble, compileTestJava
description 'Invokes cucumber acceptance tests.'
doLast {
javaexec {
workingDir = projectDir
main = 'cucumber.api.cli.Main'
classpath = configurations.testRuntime + sourceSets.test.output
args = [
'--plugin', 'pretty',
'--plugin', 'html:build/cucumber',
'--plugin', 'json:build/cucumber.json',
'--plugin', 'junit:build/cucumber.xml',
'--glue', 'app.cucumber',
'src/test/resources']
}
}
}
Am I fundamentally misunderstanding something? Is this something I should look to do another way?
The desired outcome is a single command gradle <whatever>
which: runs unit tests, builds app/
, starts an instance of it and then invokes the cucumber
task to run acceptance tests.