Gradleのtestタスクでソースコードがコピーされない

こんにちは。beaglesoftの真鍋です。

IntelliJでJavaクラスファイルを作成するところがKotlinファイルを作成してからKotlin使い始めました。

さて、先日Gradleを利用してテストを実行しよう(gradle clean test)としたところ、:test NO-SOURCEと表示されテストが実行されない事象に遭遇しました。あまりにもアタリマエのことなのでGoogleで検索しても出てこなかったため簡単にまとめてみます。

状況

プロジェクトの構成はGradleのJavaプラグインの規約に準拠したプロジェクト構成でした。

.
├── README.md
├── beagle-customer.iml
├── build
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── src
    ├── main
    │   ├── java
    │   │   └── net
    │   │       └── beaglesoft
    │   │           └── customer
    │   └── resources
    │       ├── META-INF
    │       │   └── net
    │       │       └── beaglesoft
    │       │           └── customer
    │       ├── application-prod.properties
    │       ├── application-staging.properties
    │       ├── application.properties
    │       ├── db
    │       │   └── migration
    │       ├── logback-spring.xml
    │       ├── static
    │       └── templates
    └── test
        ├── java
        │   └── net
        │       └── beaglesoft
        │           └── customer
        │               ├── controllers
        │               │   ├── BarControllerTest.groovy
        │               │   └── ...
        │               └── services
        │                   ├── FooService.groovy
        │                   └── ...
        └── resources
            ├── application.properties
            └── logback-spring.xml

また、build.gradleは特段の処理を追加することもなく以下のような標準的な内容となっていました。

group 'beagle-customer'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.1.2'
    ext {
        springBootVersion = '1.5.4.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

repositories {
    mavenCentral()
    repositories {
        mavenCentral artifactUrls: [
                'http://jasperreports.sourceforge.net/maven2',
                'http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts/'
        ]
    }
}

apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: "groovy"
apply plugin: 'idea'
apply plugin: 'jacoco'
apply plugin: 'org.springframework.boot'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

springBoot {
    mainClass = "net.beaglesoft.customer.CustomerApp"
}

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

// DOMA用の設定
processResources.destinationDir = compileJava.destinationDir
compileJava.dependsOn processResources

dependencies {
.. 省略
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.4.1'
}

原因

原因はテストファイルにありました。今回テストは[Spock](http://spockframework.org/]を利用しているため、テストファイルの保存先はjavaではなくgroovyとするのが正しいということがわかりました。

.
├── README.md
├── beagle-customer.iml
├── build
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── src
    ├── main
    │   ├── java
    │   │   └── net
    │   │       └── beaglesoft
    │   │           └── customer
    │   └── resources
    │       ├── META-INF
    │       │   └── net
    │       │       └── beaglesoft
    │       │           └── customer
    │       ├── application-prod.properties
    │       ├── application-staging.properties
    │       ├── application.properties
    │       ├── db
    │       │   └── migration
    │       ├── logback-spring.xml
    │       ├── static
    │       └── templates
    └── test
        ├── groovy
        │   └── net
        │       └── beaglesoft
        │           └── customer
        │               ├── controllers
        │               │   ├── BarControllerTest.groovy
        │               │   └── ...
        │               └── services
        │                   ├── FooService.groovy
        │                   └── ...
        └── resources
            ├── application.properties
            └── logback-spring.xml

気づいてしまえば当たり前なのですが、ミニマムプロジェクトを作成して同じようにGradleの設定を行ってビルドを実行していたところ記述するテストごとにtestディレクトリにディレクトリが作成されていることに気づいたのが最初でした。

その後Groovyプラグインのドキュメントをよく読んでみるとまさにそのことが記述されていました。

[The Groovy Plugin - Gradle User Guide Version 3.3] (https://docs.gradle.org/3.3/userguide/groovy_plugin.html#sec:groovy_project_layout)

src/test/java Test Java source

src/test/groovy Test Groovy sources. May also contain Java sources for joint compilation.

結論

ドキュメントはよく読まないといけないのですが、どこを読めばいいか(すべてを読むことは最初は難しい…)を探るためにも、単純なミニマムコードを用意してうまく行かないことを確認するのは大事ですね。

あと、Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築にはとてもおせわになりました。うまく行かないときはGoogleで検索して出てきたコードの断片をとりあえず貼り付けて動くか?なんてことをやりがちなのですが、正しい情報でないこともありました。

Gradleはどういうものかということがとてもわかり易く記述されていたので役立ちました。公式ガイドもわかりやすいのですが、紙の書籍のほうがパラパラと見れてよかったです。