I have some cucumber tests that can be run in in parallel, and some that can't. I want a way to run them all at once. The only way I can think of doing it is to run the parallel tests first and then run the rest of the tests sequentially and merge the test report somehow. I have a test framework that uses Kotlin, Cucumber and Gradle. I currently have a gradle task that reads in the tags as system properties, and based on the tags it sets the number of threads to use to run the cucumber task. I know there is a limitation on gradle vs maven for running in parallel, but maven isn't really an option for me.
This is basic gradle task that runs cucumber, using a different number of threads based on the @parallel tag being passed in:
task("cucumber") {
dependsOn("assemble", "compileTestJava")
var tags: String = getProperty("tags", "((@api) and (not @skip) and (not @bug)")
var threads: String = "1"
if(tags.contains("@parallel")) {
threads = "4"
}
doLast {
javaexec {
mainClass.set("io.cucumber.core.cli.Main")
classpath = cucumberRuntime + sourceSets.main.get().output + sourceSets.test.get().output
systemProperties(System.getProperties().mapKeys { it.key as String })
args = listOf(
"--plugin", "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm",
"--glue", "com.myproject", "src/test/resources",
"--tags", tags,
"--threads", threads
)
environment("tags", tags)
}
}
}
I am wondering if it is possible to chain 2 commands in gradle, one immediately after the other? I tried the following and there was about a 2 min delay in between one cucumber run finishing, and the other one starting:
fun runCucumber() {
var tags = ""
var threads = ""
javaexec {
mainClass.set("io.cucumber.core.cli.Main")
classpath = cucumberRuntime + sourceSets.main.get().output + sourceSets.test.get().output
systemProperties(System.getProperties().mapKeys { it.key as String })
tags = getProperty("tags", "((@api) and (not @skip) and (not @bug)")
threads = getProperty("threads", "1")
if (tags.contains("@parallel")) {
threads = "4"
}
args = listOf(
"--plugin", "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm",
"--glue", "com.myproject", "src/test/resources",
"--tags", tags,
"--threads", threads
)
environment("tags", tags)
}
exec {
if (tags.contains("@parallel")) {
javaexec {
mainClass.set("io.cucumber.core.cli.Main")
classpath = cucumberRuntime + sourceSets.main.get().output + sourceSets.test.get().output
systemProperties(System.getProperties().mapKeys { it.key as String })
tags = getProperty("tags", "(@api) and (not @parallel)")
threads = getProperty("threads", "1")
args = listOf(
"--plugin", "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm",
"--glue", "com.myproject", "src/test/resources",
"--tags", tags,
"--threads", threads
)
environment("tags", tags)
}
}
}
}
task("cucumber") {
dependsOn("assemble", "compileTestJava")
doLast {
runCucumber()
}
}
Is this the correct way to achieve what I'm asking for using gradle tasks?
It also brings up the question of whether there is a better/different way to achieve what I need, without using multiple gradle tasks or commands?
Any help would be appreciated!