Class AffectedTestTask
- All Implemented Interfaces:
Comparable<org.gradle.api.Task>,org.gradle.api.internal.DynamicObjectAware,org.gradle.api.internal.TaskInternal,org.gradle.api.Named,org.gradle.api.plugins.ExtensionAware,org.gradle.api.Task,org.gradle.util.Configurable<org.gradle.api.Task>
Execution flow:
- Detects git changes against the configured base ref
- Maps changed files to production/test classes
- Discovers which test classes are affected
- Groups FQNs by owning subproject and runs
:<module>:test --tests <fqn>once per module so that--testsfilters don't cross module boundaries
Configuration-cache safe: every input is a Gradle Property /
ListProperty / MapProperty / DirectoryProperty,
the dispatch path runs through an injected ExecOperations
service, and no Project or live build-time object is captured
by the task action. Reading the live git state and walking the source
tree happen entirely inside runAffectedTests() — that's
task-action work, which CC stores once and replays on subsequent
runs without re-resolving the task graph.
The task is deliberately marked as never up-to-date
(outputs.upToDateWhen(t -> false)) so a real git change always
triggers a re-run; that's an up-to-date concern, independent of CC.
The build cache is disabled for the same reason the up-to-date
check is: the task has no cacheable outputs (it dispatches
:test runs and writes nothing of its own), and its work depends on
live git state which the build cache cannot key on. Gradle 9.5+'s
validatePlugins requires this be declared explicitly.
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.gradle.api.Named
org.gradle.api.Named.Namer -
Field Summary
Fields inherited from interface org.gradle.api.Task
TASK_ACTION, TASK_CONSTRUCTOR_ARGS, TASK_DEPENDS_ON, TASK_DESCRIPTION, TASK_GROUP, TASK_NAME, TASK_OVERWRITE, TASK_TYPE -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionabstract org.gradle.api.provider.Property<String> Git base ref to diff against.protected abstract org.gradle.process.ExecOperationsInjected by Gradle for executing the test subprocess.abstract org.gradle.api.provider.Property<Boolean> Whentrue, the task prints the full decision trace (buckets, situation, action, action source) and exits without running any tests.abstract org.gradle.api.provider.Property<String> Format for the--explaintrace.abstract org.gradle.api.provider.Property<Long> Wall-clock timeout (in seconds) for the nested./gradlewinvocation that runs the affected / full test suite.abstract org.gradle.api.provider.ListProperty<String> Glob patterns for files that must never influence test selection.abstract org.gradle.api.provider.ListProperty<String> Suffixes/prefixes for finding implementation classes.abstract org.gradle.api.provider.Property<Boolean> Whether to include tests for implementations of changed interfaces/base classes.abstract org.gradle.api.provider.Property<Boolean> Whether to include staged (added to index) changes in the diff.abstract org.gradle.api.provider.Property<Boolean> Whether to include uncommitted (unstaged) changes in the diff.abstract org.gradle.api.provider.Property<String> getMode()Execution profile name — one of"auto","local","ci","strict".abstract org.gradle.api.provider.Property<String> abstract org.gradle.api.provider.Property<String> abstract org.gradle.api.provider.Property<String> abstract org.gradle.api.provider.Property<String> Action to take when discovery ran but one or more scanned Java files failed to parse (seeSituation.DISCOVERY_INCOMPLETE).abstract org.gradle.api.provider.Property<String> abstract org.gradle.api.provider.Property<String> abstract org.gradle.api.provider.ListProperty<String> Production source directories the plugin must treat as out-of-scope.abstract org.gradle.api.provider.ListProperty<String> Test source directories (e.g.abstract org.gradle.api.file.DirectoryPropertyThe root project directory (resolved at configuration time).abstract org.gradle.api.provider.ListProperty<String> Production source directories relative to each module root.abstract org.gradle.api.provider.ListProperty<String> Discovery strategies to use for finding affected tests.Map of subproject directory (relative to the root project, empty string for the root project itself) to the Gradle path of that subproject (e.g.abstract org.gradle.api.provider.ListProperty<String> Test source directories relative to each module root.abstract org.gradle.api.provider.ListProperty<String> Suffixes used by the naming strategy to find test classes.abstract org.gradle.api.provider.ListProperty<String> Names of the Gradle test tasks the dispatch path may invoke.abstract org.gradle.api.provider.Property<Integer> How many levels of transitive dependencies to follow when thetransitivestrategy is enabled.voidDetects affected tests and executes them via a Gradle subprocess.Methods inherited from class org.gradle.api.DefaultTask
compareTo, configure, dependsOn, doFirst, doFirst, doFirst, doLast, doLast, doLast, finalizedBy, getActions, getAnt, getDependsOn, getDescription, getDestroyables, getDidWork, getEnabled, getExtensions, getFinalizedBy, getGroup, getInputs, getLocalState, getLogger, getLogging, getMustRunAfter, getName, getOutputs, getPath, getProject, getShouldRunAfter, getState, getTaskDependencies, getTemporaryDir, getTimeout, hasProperty, mustRunAfter, onlyIf, onlyIf, onlyIf, property, setActions, setDependsOn, setDescription, setDidWork, setEnabled, setFinalizedBy, setGroup, setMustRunAfter, setOnlyIf, setOnlyIf, setOnlyIf, setProperty, setShouldRunAfter, shouldRunAfter, usesServiceMethods inherited from class org.gradle.api.internal.AbstractTask
acceptServiceReferences, appendParallelSafeAction, doNotTrackState, doNotTrackStateIf, getAsDynamicObject, getIdentityPath, getImpliesSubProjects, getLifecycleDependencies, getOnlyIf, getReasonNotToTrackState, getReasonsNotToTrackState, getReasonTaskIsIncompatibleWithConfigurationCache, getRequiredServices, getServices, getSharedResources, getStandardOutputCapture, getTaskActions, getTaskIdentity, getTemporaryDirFactory, hasTaskActions, injectIntoNewInstance, isCompatibleWithConfigurationCache, isEnabled, isHasCustomActions, notCompatibleWithConfigurationCache, prependParallelSafeAction, restoreOnlyIf, restoreTaskActions, setImpliesSubProjectsMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.gradle.api.Task
doNotTrackState, notCompatibleWithConfigurationCache
-
Constructor Details
-
AffectedTestTask
public AffectedTestTask()
-
-
Method Details
-
getBaseRef
Git base ref to diff against. Default:"origin/master". Override via-PaffectedTestsBaseRef=....- Returns:
- the base ref property
-
getIncludeUncommitted
Whether to include uncommitted (unstaged) changes in the diff. Default:false— committed-only, so a local run picks the same tests CI would pick on the same HEAD, and two runs on the same commit are deterministic. Flip totrueinbuild.gradleif you iterate on tests locally and want WIP to seed the diff.- Returns:
- the include uncommitted property
-
getIncludeStaged
Whether to include staged (added to index) changes in the diff. Default:false— seegetIncludeUncommitted()for the rationale; both knobs move together on the CI-first defaults.- Returns:
- the include staged property
-
getStrategies
Discovery strategies to use for finding affected tests. Valid values:"naming","usage","impl","transitive". Default: all four.- Returns:
- the strategies list property
-
getTransitiveDepth
How many levels of transitive dependencies to follow when thetransitivestrategy is enabled. Range: 0 (disabled) to 5. Default:4— matches the depth most Java controller → service → repository chains actually reach in Modulr-shaped codebases while leaving one level of margin. The pre-v2 default was2, which under-reached on any MR that crossed more than one seam; consumers reading this Javadoc were being told they still needed to set4explicitly — they do not.- Returns:
- the transitive depth property
-
getTestSuffixes
Suffixes used by the naming strategy to find test classes. Default:["Test", "IT", "ITTest", "IntegrationTest"].- Returns:
- the test suffixes list property
-
getSourceDirs
Production source directories relative to each module root. Default:["src/main/java"].- Returns:
- the source dirs list property
-
getTestDirs
Test source directories relative to each module root. Default:["src/test/java"].- Returns:
- the test dirs list property
-
getTestTaskNames
Names of the Gradle test tasks the dispatch path may invoke. Default:["test"]. SeeAffectedTestsExtension.getTestTaskNames()for the routing semantics.- Returns:
- the test task names list property
-
getIgnorePaths
Glob patterns for files that must never influence test selection. Optional — when unset, the core config's default list applies.- Returns:
- the ignore paths list property
-
getOutOfScopeTestDirs
@Input @Optional public abstract org.gradle.api.provider.ListProperty<String> getOutOfScopeTestDirs()Test source directories (e.g."api-test/src/test/java") whose contents the plugin must not dispatch via theaffectedTesttask.- Returns:
- the out-of-scope test dirs list property
-
getOutOfScopeSourceDirs
@Input @Optional public abstract org.gradle.api.provider.ListProperty<String> getOutOfScopeSourceDirs()Production source directories the plugin must treat as out-of-scope.- Returns:
- the out-of-scope source dirs list property
-
getIncludeImplementationTests
Whether to include tests for implementations of changed interfaces/base classes. Default:true.- Returns:
- the include implementation tests property
-
getImplementationNaming
Suffixes/prefixes for finding implementation classes. Default:["Impl", "Default"].- Returns:
- the implementation naming list property
-
getMode
Execution profile name — one of"auto","local","ci","strict". Unset resolves to"auto"in the core config, which detects CI from common env vars.- Returns:
- the mode property
-
getOnEmptyDiff
- Returns:
- the on-empty-diff situation action property
-
getOnAllFilesIgnored
- Returns:
- the on-all-files-ignored situation action property
-
getOnAllFilesOutOfScope
- Returns:
- the on-all-files-out-of-scope situation action property
-
getOnUnmappedFile
- Returns:
- the on-unmapped-file situation action property
-
getOnDiscoveryEmpty
- Returns:
- the on-discovery-empty situation action property
-
getOnDiscoveryIncomplete
@Input @Optional public abstract org.gradle.api.provider.Property<String> getOnDiscoveryIncomplete()Action to take when discovery ran but one or more scanned Java files failed to parse (seeSituation.DISCOVERY_INCOMPLETE). One of"selected","full_suite","skipped". Unset falls through to theModedefault (CI and STRICT escalate tofull_suite; LOCAL keeps the partial selection).- Returns:
- the on-discovery-incomplete property
-
getGradlewTimeoutSeconds
Wall-clock timeout (in seconds) for the nested./gradlewinvocation that runs the affected / full test suite.0disables the timeout (pre-v1.9.22 default: wait indefinitely). Positive values deadline the child: the task destroys the process tree after the interval and fails the build.Kept
@Optionalso that zero-config callers skip the timeout entirely — opting in is explicit. Must be>= 0; the core config builder rejects negative values at build-config time.- Returns:
- the gradlew timeout property in seconds
-
getExplain
Whentrue, the task prints the full decision trace (buckets, situation, action, action source) and exits without running any tests. Used by operators to answer "why did this MR land on that outcome?" without having to enable debug logs.Marked
@Internalrather than@Inputbecause flipping the explain flag must not invalidate a cached execution — it changes only the lifecycle logging, never the set of tests Gradle would actually run.- Returns:
- the explain flag property
-
getExplainFormat
Format for the--explaintrace."text"(the default) produces the human-readable line-oriented trace every adopter has been consuming since v2;"json"produces a compact single-line JSON object with the same fields, suitable for dashboard / telemetry pipelines that previously had to regex-parse the text trace and broke every time the trace shape evolved (issue #53).@Internalfor the same reason asgetExplain(): format selection only changes lifecycle logging, never the set of tests Gradle would run.- Returns:
- the explain format property
-
getSubprojectPaths
Map of subproject directory (relative to the root project, empty string for the root project itself) to the Gradle path of that subproject (e.g.":services:payment"). Populated automatically by the plugin and used to group affected test FQNs by their owning module.- Returns:
- the subproject dirs map property
-
getRootDir
@Internal public abstract org.gradle.api.file.DirectoryProperty getRootDir()The root project directory (resolved at configuration time).- Returns:
- the root dir property
-
getExecOperations
@Inject protected abstract org.gradle.process.ExecOperations getExecOperations()Injected by Gradle for executing the test subprocess.- Returns:
- the exec operations service
-
runAffectedTests
public void runAffectedTests()Detects affected tests and executes them via a Gradle subprocess.
-