如何在gradle中与多个测试源集共享公共共享文件夹

yyyllmsg  于 2023-03-13  发布在  其他
关注(0)|答案(1)|浏览(154)

我的测试源代码结构如下:

test
   testFunctional
   testIntegration
   testSupport

testSupport文件夹包含要在所有测试文件夹之间共享的公共代码。
gradle中源集的定义如下所示:

test {
        java {
            srcDirs = ['src/test/java', 'src/testSupport/java']
        }
        resources {
            srcDirs = ['src/test/resources']
        }
    }

    functionalTest {
        java {
            srcDirs = ['src/testFunctional/java', 'src/testSupport/java']
        }
        resources {
            srcDirs = ['src/testFunctional/resources']
        }
    }

    integrationTest {
        java {
            srcDirs = ['src/testIntegration/java', 'src/testSupport/java']
        }
        resources {
            srcDirs = ['src/testIntegration/resources']
        }
    }
}

IntelliJ目前抱怨“检测到重复的内容根”,指的是同一个“src/testSupport/java”文件夹在多个源集之间共享。
您是否有更优雅的解决方案来实现gradle中测试文件夹之间的代码共享,而无需使用多模块方法?

lsmepo6l

lsmepo6l1#

我想先说你应该使用Gradle Test Fixtures,在你提问的时候这是不可能的,但是现在它工作得很好。
也就是说,这个问题仍然会出现,例如,如果你想在JVM Test Suite plugin的套件之间共享代码,这个插件解决了很多开箱即用的问题;可惜不是重复的来源之一。
以下是此问题的三种备选解决方案:
1.在测试suites中共享testFixtures
1.复制源文件并多次编译它们。
1.通过testFixture共享测试。

在测试suites中共享testFixtures

结合两个内置Gradle插件的最佳解决方案。

testing.suites.named<JvmTestSuite>("...").configure { // this: JvmTestSuite
    dependencies {
        implementation(project())
        implementation(testFixtures(project()))
    }
}

复制源文件并对其进行多次编译。

我有一个类似的问题here,并解决了它的副本。采用它到你的例子上面,它会是这样的:

val copyFunctionalTestSupportClasses by tasks.registering<Copy>() {
    from("src/testSupport/java")
    into("src/testFunctional-testSupport/java")
}
java.sourceSets.named("functionalTest").configure {
    java.srcDir(copyFunctionalTestSupportClasses)
}
val copyIntegrationTestSupportClasses by tasks.registering<Copy>() {
    from("src/testSupport/java")
    into("src/testIntegration-testSupport/java")
}
java.sourceSets.named("integrationTest").configure {
    java.srcDir(copyIntegrationTestSupportClasses)
}
java.sourceSets.named("test").configure {
    // Leave it alone, use the original;
    java.srcDir("src/testSupport/java")
    // or do the same as the others to improve consistency between all 3 test types.
}

......是的,您看到的是正确的,srcDir获得了一个TaskProvider示例;它会在必要时执行任务。

通过测试夹具共享测试。

如果你真的想在多个任务中运行共享测试,这会更有用,看看你的设置,你可能不想这样做。我还是把它放在这里,以防有人(将来的我)寻找它😅。
1.将通用测试移至testFixtures
1.使用配置Test任务

....configure { // this: Test
    (testClassesDirs as ConfigurableFileCollection)
        .from(sourceSets["testFixtures"].output.classesDirs)
}

这将使Gradle测试运行器扫描testFixtures类以查找@Test。不过这很奇怪,因为fixtures不应包含测试。
正确的解决方案是:

java {
    registerFeature("sharedTests") {
        usingSourceSet(sourceSets.create("sharedTest"))
        disablePublication()
    }
}
dependencies {
    "sharedTestImplementation"(project)
    "sharedTestImplementation"(testFixtures(project))
    "sharedTestImplementation"(...) // any normal dependencies
}
....configure { // this: Test
    // This adds the @Test classes from sharedTest to each configured Test class.
    testClassesDirs = files(
        testClassesDirs, // Keep original.
        sourceSets["sharedTest"].output.classesDirs,
    )
}
dependencies {
    // Add a dependency on the new "feature" to the classpath of the Test task.
    implementation(project) { // or project() for TestSuites
        capabilities {
            // Sadly an internal API need to be used,
            requireCapability(org.gradle.internal.component.external.model.ProjectDerivedCapability.ProjectDerivedCapability(project, "sharedTests"))
            // or, if you prefer, hard-code it:
            requireCapability("${project.group}:${project.name}-shared-tests")
        }
    }
}

相关问题