簡體   English   中英

如何向 Gradle 添加新的源集?

[英]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 及更高版本中記錄的解決方案


總結兩個舊答案(獲得兩個世界的最佳和最小可行):

先說幾句暖心話:

  1. 首先,我們需要定義sourceSet

     sourceSets { integrationTest }
  2. 接下來我們從test擴展sourceSet ,因此我們使用test.runtimeClasspath (包括來自testtest本身的所有依賴項)作為派生sourceSet的類路徑:

     sourceSets { integrationTest { compileClasspath += sourceSets.test.runtimeClasspath runtimeClasspath += sourceSets.test.runtimeClasspath // ***) } }
    • 注意)不知何故,需要重新聲明/擴展sourceSets.integrationTest.runtimeClasspath ,但應該無關緊要,因為runtimeClasspath總是擴展output + runtimeSourceSet ,不要理解它
  3. 我們定義了一個專門用於運行集成測試的任務:

     task integrationTest(type: Test) { }
  4. 配置integrationTest測試類和類路徑使用。 java插件的默認值使用test sourceSet

     task integrationTest(type: Test) { testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath }
  5. (可選)測試后自動運行

     integrationTest.dependsOn 測試

  6. (可選)check中添加依賴項(因此它始終在執行buildcheck時運行)

     tasks.check.dependsOn(tasks.integrationTest)
  7. (可選)將 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 插件門戶鏈接是:

  1. 星雲面
  2. 星雲.integtest

如果你正在使用

要讓 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM