Get Test class names using Tooling API

I am trying to use the Tooling API to get a list of the Java test classes that will execute if I then run the test task, but I don’t want the tests to actually run at this point, I just want the names of the classes that will run.

Currently I can use…

myProjectConnection.newTestLauncher()
   .forTasks(":myProject:test")
   .addProgressListener(testNameRecorder, OperationType.TEST)
   .run();

where testNameRecorder takes any ProgressEvent with descriptor JvmTestOperationDescriptor and saves the JvmTestOperationDescriptor::getClassName

That gets all the class names correctly, but obviously also runs the tests.

I was hoping I could add something like .withArguments("--dry-run") as shown here but this doesn’t seem to work.

Is there a way to do this?

I was thinking of an init script with…

test {
  dryRun = true
}

but I just get…
Could not set unknown property 'dryRun' for task ':myProject:test' of type org.gradle.api.tasks.testing.Test.

I’m not sure dryRun would work anyway as I don’t know how much it skips - the whole test or does it enumerate all test classes/methods still but just not run them?

Ah - I was on Gradle 8.1. I see a --test-dry-run option has been added in 8.3.

I can get dryRun=true to work if I change the build file but the Tooling API won’t allow that argument to be passed to the TestLauncher.

I get…

CommandLineArgumentException: Unknown command-line option "--test-dry-run"

Is it possible to add this argument in another way?

The --test-dry-run option is not an option Gradle itself.
It is an option to the tasks of type Test and has to be specified after the test task it should affect.

Whether and how this is possible with TestLauncher I don’t know, as I never used it.
But if you don’t get it done with this additional information,
why do you not use your init script a.pproach?
It just failed as you were on Gradle <8.3 which cannot work as only Gradle 8.3 introduced this option and setting.

Thanks for answering - I’ll go down the init-script root.

Is the best way of doing this these days…

 gradle.projectsEvaluated {
   rootProject {
     tasks.getByPath(':myProject:test').setDryRun(true)
   }
 }
1 Like