在IntelliJ中将Gradle源文件夹标记为测试源

25

我在gradle中设置了一个集成测试源文件夹,如下:

subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'

    sourceCompatibility = 1.8

    configurations {
        integrationTestCompile.extendsFrom testCompile
        integrationTestCompileOnly.extendsFrom integrationTestCompile
        integrationTestCompileOnly.extendsFrom testCompileOnly
        integrationTestRuntime.extendsFrom testRuntime
    }

    sourceSets {
        integrationTest {
            java {
                compileClasspath += main.output + test.output
                runtimeClasspath += main.output + test.output
                srcDir file('src/integrationTest/java')
            }
            resources.srcDir file('src/integrationTest/resources')
        }
    }

    task integrationTest(type:Test) {
        testClassesDir = sourceSets.integrationTest.output.classesDir
        classpath = sourceSets.integrationTest.runtimeClasspath
        outputs.upToDateWhen { false }
    }
}

执行测试时,这个方法非常有效,但它会导致IntelliJ的检查出问题,可能会改变测试代码的行为。IntelliJ无法将源文件夹识别为测试源。

我尝试将它们添加为这样(在subprojects中):

idea {
    module {
        testSourceDirs += file('src/integrationTest/java')
    }
}

但是这并没有什么帮助。我还尝试了手动将它们标记为测试源(上下文菜单->标记目录为->测试源根),但IntelliJ很快就会将其覆盖回普通源根。

我应该如何在Gradle中正确配置它?

我正在Ubuntu 16.04上使用IntelliJ 2016.1.3和Gradle 2.14.1。


3
在您做出更改后,您是如何重新生成您的IDEA文件的?这应该有效(我在本地测试过)- 尝试运行 $ ./gradlew cleanIdea idea - tddmonkey
我更倾向于使用不生成我的Idea配置的Gradle解决方案,因为同一存储库中还有非Gradle项目。 - Jorn
@tddmonkey,你的解决方案确实生成了正确的.iml文件,但IntelliJ没有使用它们。你知道我该怎么做吗?Java项目是另一个文件夹的子文件夹,那个文件夹是带有.idea配置文件夹的主项目。 - Jorn
你是怎么打开它的?我通常会执行 $ ./gradlew cleanIdea idea; open <name_of_project>.ipr - tddmonkey
4个回答

15

您需要确保测试源是该软件包的唯一来源

idea {
    module {
        sourceDirs -= file('src/integrationTest/java')
        testSourceDirs += file('src/integrationTest/java')
    }
}

然后您需要运行gradle cleanIdea idea以重新创建IntelliJ文件。

请确保在使用gradle的idea插件时不要同时使用IDE gradle集成,否则对iml文件的自定义更改很可能会与启用集成的IDE发生冲突。

sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir "$projectDir/src/integrationTest/java"
        }
        resources.srcDir "$projectDir/src/integrationTest/resources"
    }
}

编辑:Gradle 4.7 Idea插件现在正确标记源代码。


6
不,这并没有改变任何事情。 - Jorn
@Jorn 尝试按照我在编辑中建议的更改,不确定你的 file(),但我倾向于指定源文件的完整路径。此外,您是在Gradle中使用Idea插件还是在IntelliJ IDE中使用Gradle集成? - LazerBanana
1
@bharal,这在其他人和我那个时候是有效的,所以请详细说明一下。同时使用Gradle插件和IntelliJ Gradle插件可能会在某些情况下造成混乱和困惑。说“它不起作用”似乎不像是程序员的做法。 - LazerBanana
它运行了! 每隔几周我都会回顾这个答案,渴望有一天解决方案能够正常工作。 今天就是那一天。我注意到了 sourceDirs 中的 -=。所以你首先从 "sourceDirs" 中 删除 "integrationTest",然后将其添加到 "testSourceDirs" 中。 我以前从来没有注意过 -=。我想这是那些情况之一,其中复制/粘贴实际上是正确的方法。 - Paul Schwarz
如果您有一个annotationProcessor依赖项,它将无法正常工作。 - cdalxndr
显示剩余2条评论

7

4
这行不通。想法团队里没有人能真正提供帮助,真可惜吧? - bharal
它确实可以,但正如我所说,你的IntelliJ gradle集成很可能会接管。 - LazerBanana
如果您有一个annotationProcessor依赖项,它将无法正常工作。 - cdalxndr
对我来说很有效。如果对你不起作用,请将idea {module移动到文件的较高位置,以便首先运行它。 - Danon

4

我知道这很老了,但面对相同的问题,我在JetBrains工单中发现了一些线索,提示你应该在Gradle中声明测试sourceSet,方法如下:

sourceSets {
    integrationTest {
        test{ //<- note this, this is what flags it right for intelliJ to process it correctly
            java {
                compileClasspath += main.output + test.output
                runtimeClasspath += main.output + test.output
                srcDir file('src/integrationTest/java')
                // note that you'll need to specify the outputDir for it to work
                // I don't fully get the reasons for this (but I rarely do when it comes to gradle anyway)
                outputDir = file("build/classes/java/integrationTest")
            }
            resources {
                srcDir file('src/integrationTest/resources')
            }
        }
    }
}

这样做可以使intelliJ立即将我的integration-test文件夹识别为测试源,就像test-source一样...

[小抱怨]我找不到相应的gradle文档,并且通常情况下我会从逆向工程或本例中稀少的提示(试错+ IntelliJ youtrack ticket)中了解它的工作方式(在我看来这说明了gradle文档有多么糟糕...)

请注意,我使用的是

  • Intellij:IntelliJ IDEA 2021.3.2(旗舰版)Build #IU-213.6777.52
  • Gradle:6.7.1

2
使用Gradle 7.4+和Kotlin DSL,你可以这样做:
plugins {
    `idea`
}

idea {
    module {
        testSources.from(sourceSets.integration.get().allSource.srcDirs)
    }
}

上面的例子假设您使用coditory/gradle-integration-test-plugin(它注册了integration源集):
plugins {
    id("com.coditory.integration-test") version "1.4.5"
}

但是,如果您以其他方式注册您的集成测试源集,也应该可以工作。您可能只需要将sourceSets.integration更改为sourceSets.yourNameOfTheSourceSet

有趣!下次需要的时候我会尽量记住这个。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接