How to run a single test that is excluded - gradle

I have integration tests named with "IT" at the end and the tests are excluded by default. My build.gradle contains:
test {
if (!project.hasProperty('runITs')) {
exclude '**/**IT.class'
}
}
The check task, which is part of build, no longer runs integration tests. All tests (unit + integration) are executed with defined runITs (e.g. ./gradlew -PrunITs=1 check) if it is necessary.
It works very well. The only drawback is than I can't run single integration test with --test (used by IDE) without runITs defined. The command fails with message: No tests found for given includes: [**/**IT.class](exclude rules).
Is there any way (e.g. build variable) how to recognize the run of single test with --test and skip the exclusion?

I have found a solution. My build.gradle now contains:
test {
if (!project.hasProperty('runITs') && filter.commandLineIncludePatterns.empty) {
exclude '**/**IT.class'
}
}
When tests are run with --tests then the list commandLineIncludePatterns in filter is not empty and exclude is not applied.
Details are obvious in test task source: https://github.com/gradle/gradle/blob/dc8545eb1caf7ea99b48604dcd7b4693e79b6254/subprojects/testing-base/src/main/java/org/gradle/api/tasks/testing/AbstractTestTask.java

try invoking the test task to the specific sub-project. if the test is root try
gradle -PrunITs=1 :test --tests 'MServiceTest'
else
gradle -PrunITs=1 :sub-prj:test --tests 'MServiceTest'

Related

Gradle - Chaining test tasks with `--tests` filter

I have been at this for a few days now, let's say I have a build.gradle as follows:
ext.createRunIntegrationTestsTask = { String taskName , String buildPlatform ->
return project.tasks.create(taskName, Test.class) {
dependsOn buildPlatform
[...]
}
}
def Platforms = ["A", "B"]
for (platform in Platforms) {
println "Creating task: runIntegrationTestsPlatform$platform"
createRunIntegrationTestsTask("runIntegrationTestsPlatform$platform", "buildPlatform$platform")
}
task runIntegrationTest(type: Test) {
dependsOn 'runIntegrationTestPlatformA'
dependsOn 'runIntegrationTestPlatformB'
}
I want to be able to run the following command with the tests filter:
gradlew :runIntegrationTest --tests "com.somestuff.methodTest"
For some reason when the above command runs, it does not pass the tests filter to runIntegrationTestPlatformA and runIntegrationTestPlatformB task. Both the runIntegrationTestPlatform... tasks run the whole suite of integration tests.
The current behavior I get is for runIntegrationTestPlatform... tasks to run the whole integration test suite for the specified platform and runIntegrationTest to run the integration test suite for all platforms.
But, when I pass the --tests filter to runIntegrationTest task, it does not get propagated to the chained tasks, i.e. runIntegrationTestPlatformA and runIntegrationTestPlatformB. Instead, it runs the whole integration test suite for both platforms. I want runIntegrationTestPlatformA and runIntegrationTestPlatformB to use the tests filter passed to runIntegrationTest to only run the specified integration tests.
Is there a way to get runIntegrationTestPlatformA and runIntegrationTestPlatformB to run from runIntegrationTest with the --tests filter.
Any help would be appreciated. Thank you.
Additional Sources:
Refactor duplicated code in gradle task "type: Copy"

Gradle how to exclude 1 test file in a multi module project setup?

So we have a multi module project setup, with test all scattered in multiple modules, now we want to execute all of them but exclude 1 test file.
How could we achieve this?
I tried the following:
gradle test -PexcludeTests=*SpecificTests
but the tests get still executed.
for running a singular test I managed to fix it this way:
gradle :multi-module:test --tests '*SpecificTests'
but unfortunately the equivalent for executing all tests but 1 cannot be made with this.
Condition: we need a command we cannot use the testing filter
You can use a project property and define an optional exclude filter, which you can then use from the command line -PexcludeTests='*SpecificTests'.
test {
if (project.hasProperty('excludeTests')) {
exclude(project.property('excludeTests'))
}
}

Exclude file from Gradle test dependency

I have rather expensive tests in my gradle java project, so I would like to avoid running them too often. Unfortunately, gradle reruns the tests on every build, since some log file in the resource-folder is changing.
Is there any way to exclude log-files from the dependency checks of :processTestResources and :test? I tried to include a exclude command in my test task, but this doesn't seem to do anything. My test task is
test {
maxHeapSize = "2048m"
workingDir = "src/test/resources/test-instance"
environment "LD_LIBRARY_PATH", "xpressmp/lib:/opt/gurobi/linux64/lib"
environment "XPRESS", "xpressmp/bin"
environment "XPRESSDIR", "xpressmp"
exclude("*.log")
exclude("*.lp")
}
I think what you are after is
sourceSets {
test {
resources {
exclude '*.log'
}
}
}
Excluding in the task would only exclude the test class from running, not which files are considered input for the task.
Btw. you can also use JUnit Categories to separate your tests into Short-Running and Long-Running tests and then make different tasks or a project property to only run the fast tests or all tests or only the slow tests. Or you can split the tests in different sourcesets and make separate tasks for it.
Define a new Test task:
task notGenericNotFT( type: Test, dependsOn: testClasses ){
filter { excludeTestsMatching 'generic.*' }
// excludes a whole package, "generic". NB this is not a regex:
// '*' is simply "wildcard" and dot means dot ... other more
// sophisticated "ANT-style" patterns are available in class Test
filter { excludeTestsMatching '*_FT' }
// also exclude all test classes ending in "_FT" (e.g. for "functional test")
}
To understand where these things come from, examine class Test and class TestFilter.
Also be aware that the gradle command line parser is quite intelligent and permissive with case-sensitivity (even in Linux!), so you can do this:
...$ ./gradlew notgen
... and it will run (as long as "notgen" designates this task unambiguously).

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.

Gradle test parameter test suite

I'm new with Gradle.
My problem:
Is it possible to switch between test suites in "Gradle test" depending on parameter?
Something like:
test {
useTestNG()
{
suites 'src/test/resources/testng-'+input_parameter_as_string+'-Test.xml'
useDefaultListeners = true
}
My goal is to call: gradle test "input_parameter_as_string".
Hope you guys can help me out.
Gradle documentation lists some ways to run specific test using system property: http://www.gradle.org/docs/current/userguide/userguide_single.html#sec:java_test . To run multiple correlated tests, you can try test group (both TestNG and Gradle supports): http://testng.org/doc/documentation-main.html#test-groups .
If you insist to use your custom closure, you can always use project property. In build.gradle:
test {
useTestNG()
{
suites 'src/test/resources/testng-' + project.ext.input_parameter_as_string +'-Test.xml'
useDefaultListeners = true
}
and in command line:
gradle test -Pinput_parameter_as_string=testFoobar.
Out of the box, Gradle supports running a single test:
./gradlew test -Dtest.single=MyTestClassName

Resources