【问题标题】:Create a flat directory structure with both source and tests in Intellij/Gradle?在 Intellij/Gradle 中创建包含源代码和测试的平面目录结构?
【发布时间】:2018-06-03 18:02:02
【问题描述】:

我第一次将 Kotlin 与 Intellij 和 Gradle 一起使用(我最初的目标是在学习 Kotlin 的同时实施一个个人项目,我认为最好使用“完整”环境)。我想用一个简单的平面目录结构来组织我的项目,我的所有代码和测试都在同一个目录中。所以我希望它看起来像这样:

project
|-src
  |-MyClass.kt
  |-MyClassTest.kt
  |-MyOtherClass.kt
  |-MyOtherClassTest.kt

我已经尝试查看 Gradle 和 Intellij 的文档,但老实说,我无法对其中任何一个做出正面或反面。

Gradle 中的 Kotlin 插件似乎具有默认目录结构,但可以更改。因此,我尝试根据在搜索中找到的一些代码 sn-ps 将以下内容添加到 build.gradle 文件中:

sourceSets {
    main {
        kotlin {
            srcDirs = ['src']
            exclude('*Test.kt')
        }
    }
    test {
        kotlin {
            srcDirs = ['src']
            include('*Test.kt')
        }
    }
}

这似乎把所有的代码,包括源代码和测试,都放到了 main 中。源代码工作正常,但测试在导入“kotlin.test”包时抱怨未定义的引用。这是我完整的 build.gradle 文件(所有这些都是由 IntelliJ 预先生成的,除了 sourceSets):

buildscript {
    ext.kotlin_version = '1.2.41'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

version '1.0-SNAPSHOT'

apply plugin: 'kotlin'

sourceSets {
    main {
        kotlin {
            srcDirs = ['src']
            exclude('*Test.kt')
        }
    }
    test {
        kotlin {
            srcDirs = ['src']
            include('*Test.kt')
        }
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

然后 Intellij 具有项目结构设置,我可以使用它来将 src 文件夹标记为 Source 或 Test,但这似乎不允许您将其设置为两者。我也对模块窗口显示的内容感到困惑。在顶层它有四个蓝色框的“myproject”和一个蓝色框的“myproject”,在第一个里面是“myproject_main”和“myproject_test”,两者都有一个蓝色框。我不明白一个蓝框和四个蓝框之间的区别,或者这些东西与我的目录结构有何关系(也许不是?)。然后我不确定这些设置如何与 Gradle 交互。

总而言之,我很困惑,我什至不知道我的问题是与 Gradle 设置、Intellij 设置还是两者兼而有之。我以为这将是一项简单的任务,但它变成了一个巨大的兔子洞。理想情况下,我想创建我所描述的目录结构,但即使只是对我一直在搞乱的所有这些设置做了一个很好的解释,我也会很高兴,因为我在网上找到的资源没有帮助我完全理解。

【问题讨论】:

  • main/test 约定的优点是一大堆工具都围绕该约定进行了优化,因此可以开箱即用。如果您决定避免该约定,您将遇到极大的摩擦。

标签: gradle intellij-idea


【解决方案1】:

您需要了解的关键是 IntelliJ IDEA 要求每个目录都属于单一类型的单一源根目录。因此,即使 Gradle 允许您说与特定模式匹配的文件应视为测试源,而与此模式不匹配的文件应视为生产源,但此类配置无法正确反映在 IntelliJ IDEA 项目结构中。

另一件关键的事情是,您永远不应该在从 Gradle 导入的项目中手动更改项目结构。这将导致 IDE 和命令行构建的行为不同,并且您的更改很可能会在后续项目重新同步期间丢失。

有四个蓝框的东西叫做模块组,有一个蓝框的东西叫做模块。将 Gradle 项目导入 IntelliJ IDEA 时,会为每个 Gradle 模块创建一个模块组,然后在每个模块组下创建三个模块(用于 Gradle 模块整体、其生产源和测试源) .

如果您想将代码保存在单个目录中,那么基本上您需要将所有代码视为生产源。只是不要为测试根指定任何设置,并为所有依赖项使用常规的“编译”范围。

或者,如果您想将您的应用程序发送给用户并且不想将已编译的测试作为其中的一部分发送,您应该将生产源和测试源保存在不同的目录中。如果您创建如下结构,您仍然可以减少嵌套:

project
|-src
  |-MyClass.kt
  |-MyOtherClass.kt
|-testSrc
  |-MyClassTest.kt
  |-MyOtherClassTest.kt

【讨论】:

  • 嗯,我也很害怕。谢谢你的解释。能否详细说明一下模块组和模块的区别,模块的整体/源码/测试源码划分是干什么用的?
  • 模块组只是将模块组合成一个结构的一种方式;它没有其他意义。模块的划分允许为生产和测试源提供独立的选项集(例如依赖项)。
猜你喜欢
  • 2014-01-26
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多