Testing Gradle:如何为每个子项目运行特定的(架构)测试?

Testing Gradle:如何为每个子项目运行特定的(架构)测试?,testing,gradle,architecture,Testing,Gradle,Architecture,我有一个Gradle monolith项目,有大约50个子项目。我希望确保每个子项目中的代码都符合特定的规则,例如,每个名为*Foo的类都用Bar注释 我已经编写了一个测试,成功地扫描了类路径并断言了我感兴趣的属性 我应该把这段代码放在哪里,以便对整个项目执行它,或者对每个子项目单独执行,或者对整个代码库执行一次 我知道测试夹具,所以我可以轻松地在一个所有子项目都可以访问的类中提供逻辑。然而,我仍然需要编写一个运行共享代码的测试类,我必须为我的每个子项目都这样做 如何避免这种重复?我在找这样的东

我有一个Gradle monolith项目,有大约50个子项目。我希望确保每个子项目中的代码都符合特定的规则,例如,每个名为
*Foo
的类都用
Bar
注释

我已经编写了一个测试,成功地扫描了类路径并断言了我感兴趣的属性

我应该把这段代码放在哪里,以便对整个项目执行它,或者对每个子项目单独执行,或者对整个代码库执行一次

我知道测试夹具,所以我可以轻松地在一个所有子项目都可以访问的类中提供逻辑。然而,我仍然需要编写一个运行共享代码的测试类,我必须为我的每个子项目都这样做

如何避免这种重复?我在找这样的东西:

subprojects {
    additionalTestsFrom project(':architecture-tests')
}

编辑:使用约定插件的清洁方法,请参阅下面的旧(不鼓励的)方法

主要思想:

buildSrc/build.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
创建一个插件,它定义了任何测试所需的依赖项。 在
buildSrc/src/main/groovy/playerd.tests.gradle

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
使用此插件,并公开添加到
:架构测试中的测试类。
在
架构测试/build.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
架构测试/src/test/java/
中提供测试类

现在定义一个可用于导入架构测试的插件。 在
buildSrc/src/main/groovy/playerd.architecture tests.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
要作为子项目的一部分运行架构测试, 在
子项目/build.gradle中添加:

plugins {
    id 'playground.architecture-tests'
}

编辑:旧的、不鼓励的解决方案:

我想我明白了。我很高兴收到改进意见和想法

我有一个子项目
:体系结构测试
,其中包含我希望包含在每个其他子项目中的测试。我需要有一个专门的子项目来完成这项工作,因为我正在更改常规子项目在
子项目xxx/build.gradle
文件(子项目配置时间?)和根
build.gradle
文件(项目配置时间?)的
子项目{}
块中的配置。到目前为止,这还不是一个问题,但我无法在另一个子项目解决任何公开/可消费配置后重新配置子项目。因此,我需要从这个
子项目
块和配置中排除
:架构测试
子项目,并将必要的配置位复制到
架构测试/build.gradle
。如果我不这样做,我会得到:

无法更改依赖项配置的角色:解决后的体系结构测试:testSharedRuntimeClasspath

以下是我的解决方案:

将测试放在
架构测试/src/testShared/java/

架构测试/build.gradle

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
对于每个消费(其他)子项目(我在
subprojects{}
块的根
build.gradle
中执行):

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    testSharedClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    testSharedRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    testSharedClasses project(path: ':architecture-tests', configuration: 'exposedTestSharedClasses')
    testSharedRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestSharedRuntimeClasspath')
}

task testShared(type: Test) {
    useTestNG()

    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.testSharedClasses
    classpath = configurations.testSharedRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
// run the shared tests as part of the regular `build` (which depends on `check`)
check.dependsOn testShared

编辑:使用约定插件的清洁方法,请参阅下面的旧(不鼓励的)方法

主要思想:

buildSrc/build.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
创建一个插件,它定义了任何测试所需的依赖项。 在
buildSrc/src/main/groovy/playerd.tests.gradle

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
使用此插件,并公开添加到
:架构测试中的测试类。
在
架构测试/build.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
架构测试/src/test/java/
中提供测试类

现在定义一个可用于导入架构测试的插件。 在
buildSrc/src/main/groovy/playerd.architecture tests.gradle
中:

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
要作为子项目的一部分运行架构测试, 在
子项目/build.gradle中添加:

plugins {
    id 'playground.architecture-tests'
}

编辑:旧的、不鼓励的解决方案:

我想我明白了。我很高兴收到改进意见和想法

我有一个子项目
:体系结构测试
,其中包含我希望包含在每个其他子项目中的测试。我需要为此专门的子项目,因为我正在更改其
子项目xxx/build.gradle
文件中的常规子项目的配置(子项目配置时间?)在根
build.gradle
文件的
子项目{}
块中(项目配置时间?)。到目前为止,这还不是一个问题,但在另一个子项目解决了任何公开/可消费配置后,我无法重新配置子项目。因此,我需要从该
子项目中排除
:架构测试
子项目
块和配置,并将必要的配置位复制到
架构测试/build.gradle
。如果我不这样做,我会得到:

无法更改依赖项配置的角色:解决后的体系结构测试:testSharedRuntimeClasspath

以下是我的解决方案:

将测试放在
架构测试/src/testShared/java/

架构测试/build.gradle

plugins {
    id 'groovy-gradle-plugin'
}
plugins {
    id 'java'
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:latest.release'
    testImplementation 'org.assertj:assertj-core:latest.release'
    testImplementation 'nl.jqno.equalsverifier:equalsverifier:latest.release'

    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:latest.release'
}

tasks.withType(Test) {
    useJUnitPlatform()
}
plugins {
    id 'playground.tests' // so that we have access to JUnit, AssertJ, ...
}

dependencies {
    // add whatever you need to write your architecture tests
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// wire the required data to the exposed configurations
artifacts {
    exposedTestClasses(sourceSets.test.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestJava)
    }
    exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files
}
plugins {
    id 'playground.tests' // inherit the basic test dependencies
}

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    sharedTestClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    sharedTestRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    sharedTestClasses project(path: ':architecture-tests', configuration: 'exposedTestClasses')
    sharedTestRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestRuntimeClasspath')
}

task sharedTest(type: Test) {
    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.sharedTestClasses
    classpath = configurations.sharedTestRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn sharedTest
plugins {
    id 'java-library'
}

// I don't think it is necessary to have a special source set, though
sourceSets {
    testShared {
    }
}

// provide configurations that can be consumed by the other subprojects
configurations {
    exposedTestSharedClasses {
        canBeConsumed = true
        canBeResolved = false
    }
    exposedTestSharedRuntimeClasspath {
        canBeConsumed = true
        canBeResolved = false
    }
}

// just add some regular dependences for my shared tests
dependencies {
    // I use a platform which defines the versions/constraints. You can just add the versions below without using a platform.
    testSharedImplementation platform(project(':some-platform'))
    testSharedImplementation 'org.testng:testng'
    testSharedImplementation 'org.assertj:assertj-core'
    testSharedImplementation 'io.github.classgraph:classgraph'
}

// wire the required data to the exposed configurations
artifacts {
    // give access to the compiled (test) classes
    exposedTestSharedClasses(sourceSets.testShared.output.classesDirs.files) {
        // make sure the compilation task is run first
        builtBy(compileTestSharedJava)
    }
    // give access to the runtime classpath, containing the libraries defined above
    exposedTestSharedRuntimeClasspath sourceSets.testShared.runtimeClasspath.files
}
对于每个消费(其他)子项目(我在
subprojects{}
块的根
build.gradle
中执行):

// define the configurations that connect the task (defined below) to the exposed configurations of `:architecture-tests`
configurations {
    testSharedClasses {
        canBeConsumed = false
        canBeResolved = true
    }
    testSharedRuntimeClasspath {
        canBeConsumed = false
        canBeResolved = true
        extendsFrom testRuntimeClasspath
    }
}

dependencies {
    testSharedClasses project(path: ':architecture-tests', configuration: 'exposedTestSharedClasses')
    testSharedRuntimeClasspath project(path: ':architecture-tests', configuration: 'exposedTestSharedRuntimeClasspath')
}

task testShared(type: Test) {
    useTestNG()

    description = 'Runs the tests shared by all subprojects.'
    group = 'verification'

    // use the configurations defined above, which depends on the configurations in `:architecture-tests`
    testClassesDirs = configurations.testSharedClasses
    classpath = configurations.testSharedRuntimeClasspath

    // optional - extend the classpath with the subproject's test and integration test classpath, so that I'm able to access these tests from my shared test
    classpath += sourceSets.test.runtimeClasspath
    classpath += sourceSets.integrationTest.runtimeClasspath
}
// run the shared tests as part of the regular `build` (which depends on `check`)
check.dependsOn testShared