How to prevent gradle build from executing test task - gradle

I know that I can use the -x test option to prevent the test task from getting called. I also have something like this in my gradle script to prevent tests from being executed in certain cases:
plugins.withType(JavaPlugin).whenPluginAdded {
test {
doFirst {
if (env.equals('prod')) {
throw new StopExecutionException("DON'T RUN TESTS IN PROD!!!!")
}
}
}
}
but is there a way to configure the java plugin to removed the dependency between build -> test?

build depends on test via check. You probably don't want to remove the dependency on check as it may do other things, so you could try:
check.dependsOn.remove(test)
Do you mind if I ask why you want to do this?

You can skip tasks via the command line with the -x option:
./gradlew assembleDebug -x taskToSkip

I don't know if it is possible to remove such a dependency.
You can however skip the execution of tasks, eg: skipping all test tasks (in production) goes like this.
tasks.withType(Test).each { task ->
task.enabled = !env.equals('prod')
}

Related

gradle custom task that depends on build task without testing

I am using gradle 6.0.1
I am trying to write my on task, but I want first the the build task is executed but without tests.
I tried (from build.gradle):
task startEnv(type: GradleBuild) {
tasks = ['build']
doLast {
// START ENV CODE
}
}
However, I don't manage to find a way to call build without running tests, as I would run
gradle build -x test
Is it possible to achieve this functionality?
Another option I can use, is to check inside my startEnv task whether build already exists and run this task only if build exists - Is there a way to query whether build exists? (this is a multi module projects, so I am not sure it is enough to check whether build directory exists on the root project).
I followed the comments and tried the solution mentioned at Skip a task when running another task
I added to build.gradle:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(startEnv)) {
println("DEBUG1")
test.enabled = false
}
}
task startEnv(type: GradleBuild) {
tasks = ['build']
doLast {
// START ENV CODE
}
}
But when I run ./gradlew startEnv - it still fails with some tests that in current phase I know they should fail.
I can see the DEBUG1 print when I execute this command but the build fails with tests that are failing.
Thank you,

Gradle short task

For fust build project I use such command
gradle clean build -x checkstyleMain -x checkstyleTest -x findbugsMain -x findbugsTest -x test
How I can create short task for this?
Something like this
task short {
clean
// build-x checkstyleMain -x checkstyleTest -x findbugsMain -x findbugsTest -x test
}
I have error with -x
UPDATE
I add such
gradle.taskGraph.whenReady {
if (gradle.taskGraph.hasTask(":fastRun")) {
checkstyleMain.enabled = false
checkstyleTest.enabled = false
findbugsMain = fasle
findbugsTest = false
test = false
}
}
task fastRun {
// clean
// build
}
And run
gradle clean build fastRun
But all tasks run =(
Gradle is not lifecycle based the way Maven is. Instead of asking for a task that includes all these other tasks you do not want to do, you are better off finding a task that does what you want without including all these others.
For example, assuming you are using the java plugin:
assemble: will create all archives in the project, but not run any tests or checks
compileTestJava: will compile all main and test Java classes but will not run tests or create binaries. Unless their creation is required by a different project in a multi-project build.
???: some task that maybe does exactly what you want
And if point 3 has no answer for you, you can define a new task that will depend only on what you want to achieve and not the rest.
See the Java plugin documentation for an exhaustive list of the tasks added, including the high level ones.
Unfortunately, usual ways of skipping tasks won't work in your case just out of the box.
But you can use a TaskGraph to check whether your custom task will be executed and if it'll be, disable all the tasks you don't want to be executed. For that, you need to add such a configuration snippet:
gradle.taskGraph.whenReady {
if (gradle.taskGraph.hasTask(":short")) {
checkstyleMain.enabled = false
checkstyleTest.enabled = false
// any other task you want to skip...
}
}
This snippet should be placed into the root of the build skript. Just note, that task names could differ depending on the project structure you have.
It's waiting until the task graph is ready and if it has a task named short (that means, that this task will be executed), then it disables some other tasks.
You can add the following codes to skip the tasks,
gradle.startParameter.excludedTaskNames += "testClasses"
gradle.startParameter.excludedTaskNames += "test"

Gradle Run Task Even If Build Fails

So I'm trying to print some stuff to the console in Gradle even if the build fails. How can I do this?
I've found build.finalizedBy(taskName) but that only runs if the build finishes normally.
You can let any build continue on task failures by using the --continue parameter on Gradle invocation. If you do not want to type this parameter all the time you can use the following code in your settings.gradle:
startParameter.continueOnFailure = true
Please note that other tasks may fail due to an earlier task that failed. Using this option, tasks connected via finalizedBy will be executed, but you should only use this option if the tasks are related, even for non-failure cases.
Of course, you can also use lifecycle listeners of the Gradle object or its TaskExecutionGraph. You can use
afterTask
a full TaskExecutionListener implementation
buildFinished (for the whole build)
You can use either gradle.buildFinished or a finalizer task (as you mentioned).
In your example, build.finalizedBy(taskName) will only execute taskName if the build task executes. If the build fails before the build task executes, taskName won't be executed.
e.g., this prints a message based on the result of the build:
gradle.buildFinished { result ->
if (result.failure) {
logger.lifecycle("build failed")
} else {
logger.lifecycle("build successful")
}
}

Skip a task when running another task

I added a task to my gradle project:
task deploy() {
dependsOn "build"
// excludeTask "test" <-- something like this
doFirst {
// ...
}
}
Now the build task always runs before the deploy task. This is fine because the build task has many steps included. Now I want to explicitly disable one of these included tasks.
Usually I disable it from command line with
gradle deploy -x test
How can I exclude the test task programmatically?
You need to configure tasks graph rather than configure the deploy task itself. Here's the piece of code you need:
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(deploy)) {
test.enabled = false
}
}
WARNING: this will skip the actions defined by the test task, it will NOT skip tasks that test depends on. Thus this is not the same behavior as passing -x test on the command line
I don't know what your deploy task does, but it probably just shouldn't depend on the 'build' task. The 'build' task is a very coarse grained lifecycle task that includes tons of stuff you probably don't want.
Instead it should correctly define its inputs (probably the artifacts that you wanna deploy) and then Gradle will only run the necessary tasks to build those inputs. Then you no longer need any excludes.
I ran into a similar problem. Here is how I prevent "test" from running when I run "intTest" and want the ITs to run alone:
test {
onlyIf { !gradle.startParameter.taskNames.contains("intTest") }
}
An alternative that doesn't depend on certain tasks being run explicitly:
test {
onlyIf { !gradle.taskGraph.hasTask(":intTest") || gradle.taskGraph.hasTask(":check") }
}

How to make gradle not to mark build failed if no tests are found

As the title says, how can I make gradle not to fail a test task if no tests are found? I ran into this problem when I was using the --tests command line option with a multi-subproject project. For instance, this command below will run all tests in class FooTest from subproject A:
gradle test --tests com.foo.bar.FooTest
However, this command fails because of something like this:
Execution failed for task ':B:test'.
> No tests found for given includes: [com.foo.bar.FooTest]
BTW, I know something like below will succeed. But is it possible to make it succeed even with the test task? It's kind of annoying to type a test task name longer than test.
gradle :A:test --tests com.foo.bar.FooTest
The behavior you described is the current Gradle behavior, there is already a ticket on Gradle forum, see https://discuss.gradle.org/t/multi-module-build-fails-with-tests-filter/25835
Based on the solution described in this ticket, you can do something like that to disable the 'failIfNoTest' default behavior:
In your root project build (or better: in an InitScript in your Gradle USER_HOME dir, to make this behavior available for all your local projects)
gradle.projectsEvaluated {
subprojects {
// TODO: filter projects that does not have test task...
test {
filter {
setFailOnNoMatchingTests(false)
}
}
}
}
Then you can execute the following command without having errors if the given test doesn't exist in all sub-projects:
gradle test --tests com.foo.bar.FooTest
it seems that currently only a workaround like this is possible:
test {
afterSuite { desc, result ->
if (!desc.parent) {
if (result.testCount == 0) {
throw new IllegalStateException("No tests were found. Failing the build")
}
}
}
}
I have filed an issue with Gradle to introduce this as a simple config option: https://github.com/gradle/gradle/issues/7452
You can also run the tests only for the current project with
gradle :test --tests com.foo.bar.FooTest
Note the colon before the test task.

Resources