[英]How do I add a new sourceset to Gradle?
我想將集成測試添加到我的 Gradle 構建(版本 1.0)中。 它們應該與我的正常測試分開運行,因為它們需要將 webapp 部署到本地主機(它們測試該 webapp)。 測試應該能夠使用我的主要源集中定義的類。 我該如何做到這一點?
2021 年更新:
8 歲左右發生了很多變化。 Gradle 仍然是一個很棒的工具。 現在文檔中有一整節專門用於配置集成測試。 我建議您現在閱讀文檔。
原答案:
這花了我一段時間才弄明白,而且在線資源也不是很好。 所以我想記錄我的解決方案。
這是一個簡單的 gradle 構建腳本,除了主源集和測試源集外,還具有一個 intTest 源集:
apply plugin: "java"
sourceSets {
// Note that just declaring this sourceset creates two configurations.
intTest {
java {
compileClasspath += main.output
runtimeClasspath += main.output
}
}
}
configurations {
intTestCompile.extendsFrom testCompile
intTestRuntime.extendsFrom testRuntime
}
task intTest(type:Test){
description = "Run integration tests (located in src/intTest/...)."
testClassesDir = project.sourceSets.intTest.output.classesDir
classpath = project.sourceSets.intTest.runtimeClasspath
}
以下是我如何在不使用configurations{ }
的情況下實現這一目標的。
apply plugin: 'java'
sourceCompatibility = JavaVersion.VERSION_1_6
sourceSets {
integrationTest {
java {
srcDir 'src/integrationtest/java'
}
resources {
srcDir 'src/integrationtest/resources'
}
compileClasspath += sourceSets.main.runtimeClasspath
}
}
task integrationTest(type: Test) {
description = "Runs Integration Tests"
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath += sourceSets.integrationTest.runtimeClasspath
}
測試使用: Gradle 1.4 和 Gradle 1.6
這曾經是在 2016 年為 Gradle 2.x / 3.x 編寫的並且已經過時了! 請查看Gradle 4 及更高版本中記錄的解決方案
總結兩個舊答案(獲得兩個世界的最佳和最小可行):
先說幾句暖心話:
首先,我們需要定義sourceSet
:
sourceSets { integrationTest }
接下來我們從test
擴展sourceSet
,因此我們使用test.runtimeClasspath
(包括來自test
和test
本身的所有依賴項)作為派生sourceSet
的類路徑:
sourceSets { integrationTest { compileClasspath += sourceSets.test.runtimeClasspath runtimeClasspath += sourceSets.test.runtimeClasspath // ***) } }
sourceSets.integrationTest.runtimeClasspath
,但應該無關緊要,因為runtimeClasspath
總是擴展output + runtimeSourceSet
,不要理解它我們定義了一個專門用於運行集成測試的任務:
task integrationTest(type: Test) { }
配置integrationTest
測試類和類路徑使用。 java
插件的默認值使用test
sourceSet
task integrationTest(type: Test) { testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath }
(可選)測試后自動運行
integrationTest.dependsOn 測試
(可選)從check
中添加依賴項(因此它始終在執行build
或check
時運行)
tasks.check.dependsOn(tasks.integrationTest)
(可選)將 java,resources 添加到sourceSet
以支持自動檢測並在您的 IDE 中創建這些“部分”。 即 IntelliJ IDEA 將自動為每個集合創建sourceSet
目錄 java 和資源(如果它不存在):
sourceSets { integrationTest { java resources } }
tl;博士
apply plugin: 'java'
// apply the runtimeClasspath from "test" sourceSet to the new one
// to include any needed assets: test, main, test-dependencies and main-dependencies
sourceSets {
integrationTest {
// not necessary but nice for IDEa's
java
resources
compileClasspath += sourceSets.test.runtimeClasspath
// somehow this redeclaration is needed, but should be irrelevant
// since runtimeClasspath always expands compileClasspath
runtimeClasspath += sourceSets.test.runtimeClasspath
}
}
// define custom test task for running integration tests
task integrationTest(type: Test) {
testClassesDir = sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.integrationTest.dependsOn(tasks.test)
參考:
不幸的是,github.com/gradle/gradle/subprojects/docs/src/samples/java/customizedLayout/ build.gradle或…/gradle/…/withIntegrationTests/build.gradle上的示例代碼似乎無法處理此問題或具有不同的/更復雜/對我來說沒有更清晰的解決方案!
nebula-facet插件消除了樣板文件:
apply plugin: 'nebula.facet'
facets {
integrationTest {
parentSourceSet = 'test'
}
}
特別是對於集成測試,即使這是為您完成的,只需申請:
apply plugin: 'nebula.integtest'
每個的 Gradle 插件門戶鏈接是:
如果你正在使用
要讓 IntelliJ 將自定義源集識別為測試源根:
plugin {
idea
}
idea {
module {
testSourceDirs = testSourceDirs + sourceSets["intTest"].allJava.srcDirs
testResourceDirs = testResourceDirs + sourceSets["intTest"].resources.srcDirs
}
}
從 Gradle 4.0 開始,這對我有用。
sourceSets {
integrationTest {
compileClasspath += sourceSets.test.compileClasspath
runtimeClasspath += sourceSets.test.runtimeClasspath
}
}
task integrationTest(type: Test) {
description = "Runs the integration tests."
group = 'verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
從 4.0 版開始,Gradle 現在為源集中的每種語言使用單獨的類目錄。 因此,如果您的構建腳本使用sourceSets.integrationTest.output.classesDir
,您將看到以下棄用警告。
Gradle 現在為每種 JVM 語言使用單獨的輸出目錄,但此構建假設源集中的所有類都使用一個目錄。 此行為已被棄用,並計划在 Gradle 5.0 中刪除
要消除此警告,只需切換到sourceSets.integrationTest.output.classesDirs
。 有關詳細信息,請參閱Gradle 4.0 發行說明。
我收集到的文檔在 2012 年提出這個問題時並不是很好,但是對於在 2020 年以后閱讀此文檔的任何人:文檔中現在有一整節關於如何為集成測試添加源集。 您真的應該閱讀它,而不是在此處復制/粘貼代碼片段,然后用頭撞牆試圖弄清楚為什么 2012-2016 年的答案不太管用。
答案很可能很簡單,但比您想象的更微妙,而且您需要的確切代碼可能與我需要的代碼不同。 例如,您是否希望集成測試使用與單元測試相同的依賴項?
您可能還想將測試配置為使用 jUnit 運行:
task integrationTest(type: Test) {
...
useJunitPlatform()
}
我是 Gradle 的新手,使用 Gradle 6.0.1 JUnit 4.12。 這是我想出的辦法來解決這個問題。
apply plugin: 'java'
repositories { jcenter() }
dependencies {
testImplementation 'junit:junit:4.12'
}
sourceSets {
main {
java {
srcDirs = ['src']
}
}
test {
java {
srcDirs = ['tests']
}
}
}
請注意,主要源和測試源是分開引用的,一個在main
下,一個在 under test
下。
dependencies
下的testImplementation
項僅用於編譯test
中的源代碼。 如果您的主要代碼實際上依賴於 JUnit,那么您還需要在dependencies
下指定implementation
。
我必須指定repositories
部分才能使其正常工作,我懷疑這是最好/唯一的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.