Get tests specified by '--tests' commandline argument

My tests are run via gradle like

./gradlew -Denv=remote clean test --tests '*com.examle.Test*'

and before tests executing I need to get argument that specified tests to run ( *com.examle.Test* ).

Is it possible to extract this argument in build.gradle file?

I assume something like

tasks.withType(Test) {
    def testsToExecute = ??? //need to get "*com.examle.Test*" value
}

I’ve tried project.gradle.startParameters, test.getProperties() but there is no info regarding specified tests to run

Thank you in advance.

The values entered are available under filter.commandLineIncludePatterns. Depending on what you’re trying to do with this, there may or may not be other options. The options provided at the command line are configured relatively late in the process, so you’d need to defer accessing them until execution time (or after the task execution graph is ready).

Thanks for reply. But unfortunately tests names are not available - filter.commandLineIncludePatterns is empty (maybe it contains test names when something like “includeCategories” is used, but not for --tests).

In general I want to create named docker container (Selenoid for UI tests) with the name based on currently running tests. So I just need to get string with the test name to pass it through.

Or maybe there is another way to get this argument not in build.gradle but in the code itself?

This property does contain the values provided for --tests, but as mentioned, the configuration phase is too soon. You specifically have to wait until task execution time, which means in a task action (not configuration) or in the gradle.taskGraph.whenReady { ... } block.

Not sure that I understand correctly regarding task action - we don’t have specific task for test and just run test task.
But I’ve tried gradle.taskGraph.whenReady and it is still empty:

gradle.taskGraph.whenReady {
    println "filter.commandLineIncludePatterns:"
    project.tasks.withType(Test).all { Test t ->
        println t.filter.commandLineIncludePatterns ;
    }
    println filter.commandLineIncludePatterns
}

Am I missing something?

The exact code you posted is not valid as the last println references a property that doesn’t exist outside of the test task. Removing that line, I can paste the rest of it in any random project I have and see the commandLineIncludePatterns printed out:

% ./gradlew test --tests '*Test' --tests 'OtherTest'
filter.commandLineIncludePatterns:
[OtherTest, *Test]

I see no difference between the last two major versions, but is there a specific version you’re using?

For the task action, there’s not really anything different between a task that Gradle provides, or one that you create yourself. You can still add a task action to it. For example,

tasks.withType(Test) {
    doFirst {
        println filter.commandLineIncludePatterns
    }
}

Unlike the task graph version, this one will only execute when the test tasks are actually going to execute, and not when they’re UP-TO-DATE or a test task isn’t scheduled to run.

Yes, sorry, it was wrong copy-paste. I’ve tried inside only

Thanks for the hint with command line - for this way it shows the test names as expected.

But if I run via Intellij IDEA - filter value is still empty for any gradle configurations:

  • gradle-wrapper.properties file
  • wrapper task
  • specified location
    And the same for versions 6.8 and 7.1
    Build/run/run test IDEA settings are set to Gradle.

Maybe it is some specific way how IDEA invokes Gradle?

Why do you expect that something that is called commandLineIncludePatterns contains things you do not supply on the command line?
Using IntelliJ is not using command line and it is not simply using the command line interface, but a special tooling API to efficiently control Gradle builds.

Besides that, using commandLineIncludePatterns is bad anyway as it is internal API, not present on the TestFilter interface of the filter property, but only on the internal implementation DefaultTestFilter. In Groovy DSL this just works due to the duck-typing Groovy is using where you can use anyhting if it is available at runtime. If you would use static compilation or Kotlin DSL, you wouldn’t be able to access this field without an explicit cast to the internal class.

You probably want to use filter.includePatterns instead, which also contains patterns sent via tooling api. :slight_smile:

Thanks for detailed explanation. I was not aware that there is a difference in running directly from gradle and invoking it via IDEA.
So something like this code solved my problem

tasks.withType(Test) {
    doFirst {
        def result = filter.commandLineIncludePatterns ? filter.commandLineIncludePatterns[0] :
                filter.includePatterns ? filter.includePatterns[0] : "UI tests"
        result = result.replace("*", "")
        systemProperty "testsFilter", result
    }
}

Thanks for help!

Old topic but struggling with the same issue, With Kotlin DSL, gradle 8.3, filter.includePatterns returns nothing for cmd arguments passed in --tests argument value. @Vampire you have any idea how to solve it?

That’s exactly the opposite question.
But the answer is practically the same.
What comes in from --tests is stored in commandLineIncludePatterns of DefaultTestFilter which is not public API.

Ok, I found exact code that solves my problem in a Gradle bug report, so will paste it here for other Gradle Kotlin users:
(filter as DefaultTestFilter).commandLineIncludePatterns
this code gets value from --tests cmd args.
Found in IJ Launches all tests in a project when only one is requested when TestFilter is configured · Issue #9647 · gradle/gradle · GitHub

1 Like

@ewak That exactly solved my problem. Thank you!