Problem
The ImportOption.Predefined.GRADLE_TEST_PATTERN in ArchUnit fails to detect tests located in custom Gradle source sets (e.g., integrationTest, functionalTest, etc.) because the pattern only matches lowercase test in the build path.
Current Implementation
From com.tngtech.archunit.core.importer.ImportOption$Predefined (line ~102):
static final PatternPredicate GRADLE_TEST_PATTERN =
new PatternPredicate(".*/build/classes/([^/]+/)?test/.*");
This pattern matches paths like:
- ✅
/build/classes/java/test/ (standard test source set)
- ✅
/build/classes/kotlin/test/
- ❌
/build/classes/java/integrationTest/ (custom source set)
- ❌
/build/classes/kotlin/functionalTest/ (custom source set)
- ❌
/build/classes/java/e2eTest/ (custom source set)
Impact
When using ImportOption.DoNotIncludeTests or ImportOption.OnlyIncludeTests:
- Custom test source sets are not excluded when using
DoNotIncludeTests
- Custom test source sets are not included when using
OnlyIncludeTests
This causes incorrect behavior when architectural rules should apply to or exclude tests from custom source sets.
Example Scenario
// Gradle configuration with custom source set
sourceSets {
create("integrationTest") {
compileClasspath += sourceSets.main.get().output
runtimeClasspath += sourceSets.main.get().output
}
}
// ArchUnit test that fails to recognize integrationTest classes as tests
@AnalyzeClasses(
packages = "com.example",
importOptions = [ImportOption.DoNotIncludeTests::class]
)
class ArchitectureTest {
// This will incorrectly analyze integrationTest classes
// because the pattern doesn't recognize them as tests
}
Proposed Solution
The pattern should be more flexible to match any path segment containing "test" (case-insensitive) or "Test" suffix:
Option 1: Case-insensitive matching
".*/build/classes/([^/]+/)?(?i).*test.*/.*"
Option 2: Match common test source set naming patterns
".*/build/classes/([^/]+/)?([a-z]+)?[Tt]est(s)?/.*"
This would match:
test (standard)
integrationTest
functionalTest
e2eTest
tests (plural variant)
Workaround
Currently, users must implement custom ImportOption for each custom test source set:
public class DoNotIncludeIntegrationTests implements ImportOption {
private static final Pattern PATTERN =
Pattern.compile(".*/build/classes/([^/]+/)?integrationTest/.*");
@Override
public boolean includes(Location location) {
return !location.matches(PATTERN);
}
}
Environment
- ArchUnit version: 1.4.1
- Build tool: Gradle
- Custom source set name:
integrationTest
Problem
The
ImportOption.Predefined.GRADLE_TEST_PATTERNin ArchUnit fails to detect tests located in custom Gradle source sets (e.g.,integrationTest,functionalTest, etc.) because the pattern only matches lowercasetestin the build path.Current Implementation
From
com.tngtech.archunit.core.importer.ImportOption$Predefined(line ~102):This pattern matches paths like:
/build/classes/java/test/(standard test source set)/build/classes/kotlin/test//build/classes/java/integrationTest/(custom source set)/build/classes/kotlin/functionalTest/(custom source set)/build/classes/java/e2eTest/(custom source set)Impact
When using
ImportOption.DoNotIncludeTestsorImportOption.OnlyIncludeTests:DoNotIncludeTestsOnlyIncludeTestsThis causes incorrect behavior when architectural rules should apply to or exclude tests from custom source sets.
Example Scenario
Proposed Solution
The pattern should be more flexible to match any path segment containing "test" (case-insensitive) or "Test" suffix:
Option 1: Case-insensitive matching
".*/build/classes/([^/]+/)?(?i).*test.*/.*"Option 2: Match common test source set naming patterns
".*/build/classes/([^/]+/)?([a-z]+)?[Tt]est(s)?/.*"This would match:
test(standard)integrationTestfunctionalTeste2eTesttests(plural variant)Workaround
Currently, users must implement custom
ImportOptionfor each custom test source set:Environment
integrationTest