かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Gradle で Multi-project を作成する ( 大目次 )

  1. その1 ( 概要 )
  2. その2 ( lib+cmdapp編、Multi-project の設定ファイルと Spring を使用しないライブラリのプロジェクトを作成する )
  3. その3 ( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する )
  4. その4 ( lib+webappx2編、Multi-project の設定ファイルと Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する )
  5. その5 ( lib+webappx2編、Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する )
  6. その6 ( Multi-project は settings.gradle に include を書くだけでもよいのでは? )
  7. 番外編 ( Spring Actuator を利用してアプリ起動時にメールサーバに接続できない場合には起動を中断させる )
  8. その7 ( doma2lib+cmdapp+webapp編、Multi-project の設定ファイルと docker-compose.yml を作成する )
  9. その8 ( doma2lib+cmdapp+webapp編、doma2-lib プロジェクトを作成する )
  10. その9 ( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する )
  11. その10 ( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する2 )
  12. その11 ( doma2lib+cmdapp+webapp編、log4jdbc-log4j2 を導入してトランザクションが有効なことを確認する )
  13. その12 ( doma2lib+cmdapp+webapp編、sample-webapp プロジェクトを作成する )
  14. その13 ( doma2lib+cmdapp+webapp編、PropertiesLauncher を利用して doma2-lib の jar ファイルを外部に出す )
  15. その14 ( vuejs+springboot編、Multi-project のベースと backend-app プロジェクトを作成する )
  16. その15 ( vuejs+springboot編、frontend-app プロジェクトを作成する )
  17. 感想

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その83 )( Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップ+JUnit 5 の導入+ Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする)

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その82 )( Gradle を 4.8.1 → 5.3.1 へ、Spring Boot を 2.0.4 → 2.1.4 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップします。
    • JUnit 5 を使用できるようにします。このプロジェクトでは Spock+Geb でしかテストを書いていないので JUnit 5 は使える環境を整えるだけになります。
    • JDKOracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップします。

参照したサイト・書籍

  1. https://github.com/apache/groovy/commit/92bd96fcdfe35e502987e1846715a08a45620db1

    • Groovy で --add-opens オプションを付ける時に参照しました。

目次

  1. Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップする
  2. JUnit 5 を導入する
  3. Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする
  4. testJUnit4AndSpock タスクで出る警告を解消する
  5. 失敗するテストの原因を調査・解消する
  6. compileTestGroovy タスクで出る警告を解消する。。。ことは出来ませんでした
  7. gebTest タスクが成功するようにする

手順

Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップする

build.gradle の以下の点を変更します。

checkstyle {
    configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml")
    toolVersion = "8.19"
    sourceSets = [project.sourceSets.main]
}

..........

pmd {
    toolVersion = "6.13.0"
    sourceSets = [project.sourceSets.main]
    ignoreFailures = true
    consoleOutput = true
    ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml")
    ruleSets = []
}
  • checkstyle block で toolVersion = "8.11"toolVersion = "8.19" に変更します。
  • pmd block で toolVersion = "6.6.0"toolVersion = "6.13.0" に変更します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、PMD で何件か警告が出ました。

f:id:ksby:20190414123438p:plain

  • D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\Application.java:26: The constant name 'springProfiles' doesn't match '[A-Z][A-Z_0-9]*'
    • 定数名を SPRING_PROFILES に変更します。
  • D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\ControllerAndEventNameLogger.java:17: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
  • D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\MethodLogger.java:20: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
  • D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\RequestAndResponseLogger.java:34: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'

再度 clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、今度は BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190414131126p:plain

JUnit 5 を導入する

build.gradle の以下の点を変更します。

dependencyManagement {
    imports {
        // mavenBom は以下の URL のものを使用する
        // https://repo.spring.io/release/org/springframework/boot/spring-boot-starter-parent/2.1.4.RELEASE/
        // bomProperty に指定可能な property は以下の URL の BOM に記述がある
        // https://repo.spring.io/release/org/springframework/boot/spring-boot-dependencies/2.1.4.RELEASE/spring-boot-dependencies-2.1.4.RELEASE.pom
        mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
        mavenBom("org.junit:junit-bom:5.4.2")
    }
}

dependencies {
    ..........

    // for JUnit 5
    // junit-jupiter で junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine の3つが依存関係に追加される
    testCompile("org.junit.jupiter:junit-jupiter")
    testRuntime("org.junit.platform:junit-platform-launcher")
}

def jvmArgsForTask = [
        "-ea",
        "-Dfile.encoding=UTF-8",
        "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP"
]
def printTestCount = { desc, result ->
    if (!desc.parent) { // will match the outermost suite
        println "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
    }
}

bootRun {
    jvmArgs = jvmArgsForTask +
            ["-Dspring.profiles.active=develop"]
}

tasks.withType(Test) {
    jvmArgs = jvmArgsForTask +
            ["-Dspring.profiles.active=unittest"]
}
task testJUnit4AndSpock(type: Test) {
    // testJUnit4AndSpock タスクの jvmArgs は tasks.withType(Test) { ... } で定義している
    exclude "geb/**"

    testLogging {
        afterSuite printTestCount
    }
}
test.dependsOn testJUnit4AndSpock
test {
    // test タスクの jvmArgs は tasks.withType(Test) { ... } で定義している

    // for JUnit 5
    useJUnitPlatform()

    testLogging {
        afterSuite printTestCount
    }
}

..........

webdriverBinaries {
    chromedriver "73.0.3683.68"
    geckodriver "0.24.0"
}
def drivers = ["chrome", "firefox"]
drivers.each { driver ->
    task "${driver}Test"(type: Test) {
        // 前回実行時以降に何も更新されていなくても必ず実行する
        outputs.upToDateWhen { false }
        systemProperty "geb.env", driver
        exclude "ksbysample/**"
// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//        dependsOn startServer
//        finalizedBy stopServer

        testLogging {
            afterSuite printTestCount
        }
    }
}
task gebTest {
    dependsOn drivers.collect { tasks["${it}Test"] }
    enabled = false
}
  • dependencyManagement block の import block 内に mavenBom("org.junit:junit-bom:5.4.2") を追加します。
  • dependencies block に以下の2行を追加します。
    • testCompile("org.junit.jupiter:junit-jupiter")
    • testRuntime("org.junit.platform:junit-platform-launcher")
  • def jvmArgsForTask = [ ... ] を追加します。
  • def printTestCount = { ... } を追加します。
  • bootRun タスクの jvmArgs の設定を jvmArgsForTask 変数を利用したものに変更します。
  • tasks.withType(Test) { ... } の jvmArgs の設定を jvmArgsForTask 変数を利用したものに変更します。
  • task testJUnit4AndSpock(type: Test) { ... } を追加します。
  • test.dependsOn testJUnit4AndSpock を追加します。
  • test タスク内に以下の記述を追加します。
    • useJUnitPlatform()
    • testLogging { afterSuite printTestCount }
  • exclude "geb/**" の記述は test タスクから testJUnit4AndSpock タスクへ移動します。
  • drivers.each { driver -> task "${driver}Test"(type: Test) { ... } } 内に testLogging { afterSuite printTestCount } を追加します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

clean タスク実行 → Rebuild Project 実行 → build タスク実行をすると、テストは問題なく成功し BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190414144014p:plain

gebTest タスクも BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190414144720p:plain

Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする

IntelliJ IDEA のメインメニューから「File」-「Project Structure...」を選択して「Project Structure」ダイアログを開き、「Project SDK」で「11.0.2+9」を選択してから「OK」ボタンをクリックしてダイアログを閉じます。

f:id:ksby:20190414154450p:plain

build.gradle の以下の点を変更します。

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.1.4.RELEASE"
    id "io.spring.dependency-management" version "1.0.7.RELEASE"
    id "groovy"
    id "net.ltgt.errorprone" version "0.7.1"
    id "checkstyle"
    id "com.github.spotbugs" version "1.6.9"
    id "pmd"
    id "com.moowork.node" version "1.3.1"
    id "com.gorylenko.gradle-git-properties" version "2.0.0"
// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//    id "com.github.johnrengelman.processes" version "0.5.0"
    id "com.energizedwork.webdriver-binaries" version "1.4"
}

sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

..........

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]
tasks.named("compileTestJava").configure {
    options.errorprone.enabled = false
}

..........

dependencies {
    def spockVersion = "1.3-groovy-2.5"
    def domaVersion = "2.24.0"
    def lombokVersion = "1.18.6"
    def errorproneVersion = "2.3.3"
    def powermockVersion = "2.0.0"
    def seleniumVersion = "3.13.0"
    def spotbugsVersion = "3.1.11"

    ..........

    // for Geb + Spock
    testImplementation("org.gebish:geb-spock:2.3.1") {
        exclude group: "org.codehaus.groovy", module: "groovy-all"
    }
    ..........

}

def jvmArgsForTask = [
        "-ea",
        "-Dfile.encoding=UTF-8",
        "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP"
]
// JDK 11 に変更後、test タスク実行時に groovy と powermock が JDKの内部部分にアクセスするためにコードでリフレクションを使用
// していて WARNING が出るため、JVM の起動時オプションの --add-opens を指定して WARNING が出ないようにする
def jvmArgsAddOpens = [
        "--add-opens=java.base/java.io=ALL-UNNAMED",
        "--add-opens=java.base/java.lang=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.ref=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED",
        "--add-opens=java.base/java.net=ALL-UNNAMED",
        "--add-opens=java.base/java.security=ALL-UNNAMED",
        "--add-opens=java.base/java.util=ALL-UNNAMED",
        "--add-opens=java.base/java.util.stream=ALL-UNNAMED"
]
def printTestCount = { desc, result ->
    if (!desc.parent) { // will match the outermost suite
        println "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
    }
}

bootRun {
    jvmArgs = jvmArgsForTask +
            jvmArgsAddOpens +
            ["-Dspring.profiles.active=develop"]
}

tasks.withType(Test) {
    jvmArgs = jvmArgsForTask +
            jvmArgsAddOpens +
            ["-Dspring.profiles.active=unittest"]
}
  • plugins block の以下の点を変更します。
    • id "net.ltgt.errorprone" version "0.0.14"id "net.ltgt.errorprone" version "0.7.1"
  • sourceCompatibility、targetCompatibility に指定する値を 1.8JavaVersion.VERSION_11 に変更します。
  • compileJava.options.compilerArgs += [ ... ] を削除します。
  • tasks.named("compileTestJava").configure { options.errorprone.enabled = false } を追加します。
  • dependencies block の以下の点を変更します。
    • def errorproneVersion = "2.3.1"def errorproneVersion = "2.3.3"
  • def jvmArgsAddOpens = [ ... ] を追加します。Spring Boot 2.0.x の Web アプリを 2.1.x へバージョンアップする ( その15 )( JDK を 8u202 → 11.0.2+9 に変更する ) で指定したものと同じものを指定しておきます。
  • bootRun { ... }tasks.withType(Test) { ... } 内の jvmArgs の設定に jvmArgsAddOpens + を追加します。
  • groovy も 2.5 にバージョンアップします。
    • dependencies block 内で def spockVersion = "1.3-groovy-2.4"def spockVersion = "1.3-groovy-2.5" に変更します。
    • testImplementation("org.gebish:geb-spock:2.3.1")testImplementation("org.gebish:geb-spock:2.3.1") { exclude group: "org.codehaus.groovy", module: "groovy-all" } に変更します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

IntelliJ IDEA のメインメニューから「Run」-「Edit Configurations...」を選択して「Run/Debug Configurations」ダイアログを開き、画面左側のツリーから「Templates」-「JUnit」を選択後、画面右側の「VM options」に build.gradle の def jvmArgsAddOpens = [ ... ] に記述したオプションを追加します。

f:id:ksby:20190414194725p:plain

また追加した結果 IntelliJ IDEA からテストを実行しようとすると Command line is too long. のエラーメッセージが表示されて実行できなくなるので、画面右側の「Shorten command line」で「JAR manifest」を選択します。

f:id:ksby:20190414195417p:plain

clean タスク実行 → Rebuild Project 実行 → build タスク実行して出力される以下のエラーメッセージを取り除きます。

  • エラー: An unhandled exception was thrown by the Error Prone static analysis plugin.
    • このエラーメッセージが出る箇所は PMD の @SuppressWarnings が付与されているので、@SuppressWarnings({"PMD.UnusedPrivateMethod"})@SuppressWarnings({"PMD.UnusedPrivateMethod", "UnusedMethod"}) に変更します。
  • 警告:[JavaTimeDefaultTimeZone] LocalDateTime.now() is not allowed because it silently uses the system default time-zone. You must pass an explicit time-zone (e.g., ZoneId.of("America/Los_Angeles")) to this method.
    • LocalDateTime.now()LocalDateTime.now(ZoneId.of("Asia/Tokyo")) に変更します。

ここまでやると以下の状態になります。

f:id:ksby:20190414200539p:plain f:id:ksby:20190414200639p:plain

  • compileTestGroovy タスクで警告が出る。
  • testJUnit4AndSpock タスクで警告が出る。
  • テストが1件失敗する。

testJUnit4AndSpock タスクで出る警告を解消する

出たのは以下3件のメッセージでした。

  • WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.util.stream.Collectors()
  • WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.nio.charset.StandardCharsets()
  • WARNING: Illegal reflective access by org.powermock.reflect.internal.WhiteboxImpl (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-reflect/2.0.0/cd452bc345ec9f88ec5efecd41139de0cb1d4265/powermock-reflect-2.0.0.jar) to method java.util.regex.Pattern.clazz(boolean)

build.gradle と IntelliJ IDEA の「Edit Configurations...」-「JUnit」の設定に以下のオプションを追加します。

  • --add-opens=java.base/java.util.stream=ALL-UNNAMED
  • --add-opens=java.base/java.nio.charset=ALL-UNNAMED
  • --add-opens=java.base/java.util.regex=ALL-UNNAMED

失敗するテストの原因を調査・解消する

エラーの原因を調べるために Project Tool Window で src/test/groovy/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample''」を選択してテストを実行してみると、

f:id:ksby:20190414210930p:plain

テストが失敗したのは src/test/groovy/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput02FormValidatorTest.groovy で、以下のように実装されていました。

    @RunWith(PowerMockRunner)
    @PowerMockRunnerDelegate(SpringRunner)
    @SpringBootTest
    @PrepareForTest(EmailValidator)
    @PowerMockIgnore("javax.management.*")
    static class InquiryInput02FormValidator_メールアドレス {

        @Autowired
        private InquiryInput02FormValidator input02FormValidator

        ..........

@PowerMockIgnore("javax.management.*") を変更し忘れていただけでした。。。 @PowerMockIgnore("javax.management.*")@PowerMockIgnore(["javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*", "com.sun.org.apache.xalan.*"]) に変更します。ksbysample-webapp-lending と同じ変更だと Caused by: java.lang.IllegalAccessError: class com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl (in unnamed module @0x12e035a8) cannot access class jdk.xml.internal.JdkXmlUtils (in module java.xml) because module java.xml does not export jdk.xml.internal to unnamed module @0x12e035a8 というエラーメッセージが表示されたので、, "com.sun.org.apache.xalan.*" を追加しています。

compileTestGroovy タスクで出る警告を解消する。。。ことは出来ませんでした

WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to method java.util.AbstractCollection.hugeCapacity(int) というエラーメッセージが出ているので compileTestGroovy タスクの jvmArgs にも --add-opens オプションを設定しようと思い設定方法を調べたところ、gradle/gradle に Unable to add multiple --add-opens args to forked Groovy compiler #7045 という Issue を見つけました。

試してみたところ "--add-opens" を1行だけ書いた時は問題ないのですが、以下のように2行記述すると、

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]
tasks.named("compileTestJava").configure {
    options.errorprone.enabled = false
}
compileTestGroovy {
    options.forkOptions.jvmArgs += [
            "--add-opens", "java.base/java.util=ALL-UNNAMED",
            "--add-opens", "java.base/java.lang.annotation=ALL-UNNAMED"
    ]
}

下の画像のエラーメッセージが表示されます。

f:id:ksby:20190415225416p:plain

他にも調べてみましたがさっぱり解決方法が分かりませんでした。Issue のクローズ待ちでしょうか。。。 今回は compileTestGroovy の警告メッセージは解消するのは諦めます。

ここまでの対応で clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと compileTestGroovy タスクで警告のメッセージが出ますが、BUILD SUCCESSFUL のメッセージが表示されるようになりました。

f:id:ksby:20190415231548p:plain

gebTest タスクが成功するようにする

gebTest タスクを実行すると1件警告が出ます。

  • WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.beans.Introspector(java.lang.Class,java.lang.Class,int)

java.beans は https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/beans/package-summary.html を見ると Module java.desktop と書かれていたので、

f:id:ksby:20190416062245p:plain

build.gradle と IntelliJ IDEA の「Edit Configurations...」-「JUnit」の設定に "--add-opens=java.desktop/java.beans=ALL-UNNAMED" を追加します。

def jvmArgsAddOpens = [
        "--add-opens=java.base/java.io=ALL-UNNAMED",
        "--add-opens=java.base/java.lang=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.ref=ALL-UNNAMED",
        "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED",
        "--add-opens=java.base/java.net=ALL-UNNAMED",
        "--add-opens=java.base/java.nio.charset=ALL-UNNAMED",
        "--add-opens=java.base/java.security=ALL-UNNAMED",
        "--add-opens=java.base/java.util=ALL-UNNAMED",
        "--add-opens=java.base/java.util.regex=ALL-UNNAMED",
        "--add-opens=java.base/java.util.stream=ALL-UNNAMED",
        "--add-opens=java.desktop/java.beans=ALL-UNNAMED"
]

これで gebTest タスクは正常に終了するようになりました。

f:id:ksby:20190416063337p:plain

以上で今回の boot-npm-geb-sample プロジェクトのバージョンアップ作業は完了です。

履歴

2019/04/16
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その82 )( Gradle を 4.8.1 → 5.3.1 へ、Spring Boot を 2.0.4 → 2.1.4 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その81 )( eslint を 4.19.1 → 5.16.0 へ、windows-build-tools を 3.1.0 → 5.1.0 へ、jest を 23.4.1 → 24.7.1 へ、postcss-cli を 4.1.1 → 6.1.2 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Gradle を 4.8.1 → 5.3.1 へ、Spring Boot を 2.0.4 → 2.1.4 へバージョンアップします。
    • 依存関係にあるモジュールも一部を除き最新バージョンにバージョンアップします。

参照したサイト・書籍

目次

  1. Gradle を 4.8.1 → 5.3.1 へバージョンアップする
  2. Spring Boot を 2.0.4 → 2.1.4 へバージョンアップする

手順

Gradle を 4.8.1 → 5.3.1 へバージョンアップする

build.gradle の wrapper タスクの記述を以下のように変更します。

wrapper {
    gradleVersion = "5.3.1"
    distributionType = Wrapper.DistributionType.ALL
}
  • gradleVersion = "4.8.1"gradleVersion = "5.3.1" に変更します。

コマンドプロンプトから gradlew wrapper --gradle-version=5.3.1gradlew --version コマンドを実行します。

f:id:ksby:20190413211524p:plain

gradlew --version コマンド実行時にファイルをダウンロードしていることを示す "Downloading" のメッセージが表示されませんでした。。。?  gradlew wrapper コマンドを実行してみると build.gradle にエラーがあるというメッセージが表示されます。

f:id:ksby:20190413224840p:plain

build.gradle の修正と gradlew wrapper コマンドを繰り返し、最終的には build.gradle の以下の点を変更しました。

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.0.4.RELEASE"
    id "io.spring.dependency-management" version "1.0.6.RELEASE"
    id "groovy"
    id "net.ltgt.errorprone" version "0.0.14"
    id "checkstyle"
    id "com.github.spotbugs" version "1.6.9"
    id "pmd"
    id "com.moowork.node" version "1.2.0"
    id "com.gorylenko.gradle-git-properties" version "1.5.1"
// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//    id "com.github.johnrengelman.processes" version "0.5.0"
    id "com.energizedwork.webdriver-binaries" version "1.4"
}

..........

// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//// for Geb + Spock Integration Test
//task startServer(type: com.github.jengelman.gradle.plugins.processes.tasks.JavaFork) {
//    jvmArgs = [
//            "-Dspring.profiles.active=develop",
//            "-Dlogging.level.root=OFF",
//            "-Dlogging.level.org.springframework.web=OFF",
//            "-Dlogging.level.jdbc.sqlonly=OFF",
//            "-Dlogging.level.jdbc.sqltiming=OFF",
//            "-Dlogging.level.jdbc.audit=OFF",
//            "-Dlogging.level.jdbc.resultset=OFF",
//            "-Dlogging.level.jdbc.resultsettable=OFF",
//            "-Dlogging.level.jdbc.connection=OFF"
//    ]
//    classpath += sourceSets.main.runtimeClasspath
//    main = "${mainClass}"
//    doLast {
//        Thread.sleep(15000)
//    }
//}
//task stopServer {
//    doLast {
//        startServer.processHandle.abort()
//    }
//}
webdriverBinaries {
    chromedriver "73.0.3683.68"
    geckodriver "0.24.0"
}
def drivers = ["chrome", "firefox"]
drivers.each { driver ->
    task "${driver}Test"(type: Test) {
        // 前回実行時以降に何も更新されていなくても必ず実行する
        outputs.upToDateWhen { false }
        systemProperty "geb.env", driver
        exclude "ksbysample/**"
// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//        dependsOn startServer
//        finalizedBy stopServer
    }
}
task gebTest {
    dependsOn drivers.collect { tasks["${it}Test"] }
    enabled = false
}
..........
  • SpotBugs の gradle plugin が 1.6.2 だと Gradle 5.3.1 に対応していないようなので 1.6.9 にバージョンアップしました。plugins block で id "com.github.spotbugs" version "1.6.2"id "com.github.spotbugs" version "1.6.9" に変更しています。
  • gradle-processes plugin の設定を記載している箇所でエラーが発生し、API changes with Gradle 5.3 という Issue も作成されていました。Gradle 5.3 で gradle-processes plugin が呼び出している internal API の仕様が変わったようです。gradle-processes plugin の設定を全てコメントアウトします。
    • plugins block で id "com.github.johnrengelman.processes" version "0.5.0"コメントアウトしました。
    • task startServer と task stopServer をコメントアウトしました。
    • Geb のテストタスクを動的生成している drivers.each { driver -> ... }dependsOn startServerfinalizedBy stopServerコメントアウトしました。

これで gradlew wrapper コマンドが正常終了するようになりました。また gradlew、gradlew.bat に DEFAULT_JVM_OPTS の設定が追加されたので set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"set DEFAULT_JVM_OPTS="-Xmx4096m" "-Xms4096m" に変更します。

gradle/wrapper/gradle-wrapper.properties は以下の内容になります。

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されました。

f:id:ksby:20190413231123p:plain

Spring Boot を 2.0.4 → 2.1.4 へバージョンアップする

以下の方針でバージョンアップします。

  • Spring Boot を 2.0.4 → 2.1.4 にバージョンアップする。
  • Gradle の Plugin も com.github.spotbugs 以外は最新バージョンにする。
  • SpotBugs は gradle plugin(com.github.spotbugs) は 1.6.9、本体は 3.1.11 にする。
  • error-prone は現状維持。バージョンアップは JDK 11 に上げる時に行う。
  • checkstyle, pmd は後回し。
  • JUnit 5 の導入は後回し。

build.gradle の以下の点を変更します。

buildscript {
    ext {
        group "ksbysample"
        version "2.1.4-RELEASE"
    }
    repositories {
        mavenCentral()
        maven { url "https://plugins.gradle.org/m2/" }
    }
}

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.1.4.RELEASE"
    id "io.spring.dependency-management" version "1.0.7.RELEASE"
    id "groovy"
    id "net.ltgt.errorprone" version "0.0.14"
    id "checkstyle"
    id "com.github.spotbugs" version "1.6.9"
    id "pmd"
    id "com.moowork.node" version "1.3.1"
    id "com.gorylenko.gradle-git-properties" version "2.0.0"
// Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする
//    id "com.github.johnrengelman.processes" version "0.5.0"
    id "com.energizedwork.webdriver-binaries" version "1.4"
}

..........

configurations {
    // annotationProcessor と testAnnotationProcessor、compileOnly と testCompileOnly を併記不要にする
    testAnnotationProcessor.extendsFrom annotationProcessor
    testImplementation.extendsFrom compileOnly

    // for Doma 2
    domaGenRuntime
}

..........

spotbugs {
    // SpotBugs のレポートファイルは Firefox で見ると文字化けしない
    toolVersion = "3.1.11"
    ignoreFailures = true
    effort = "max"
    excludeFilter = file("${rootProject.projectDir}/config/spotbugs/spotbugs-exclude-filter.xml")
    spotbugsTest.enabled = false
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
    reports {
        xml.enabled = false
        html.enabled = true
    }
}

pmd {
    toolVersion = "6.6.0"
    sourceSets = [project.sourceSets.main]
    ignoreFailures = true
    consoleOutput = true
    ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml")
    ruleSets = []
}
pmdMain {
    def backupLoggerLevel
    doFirst {
        backupLoggerLevel = logger.context.level
        logger.context.level = LogLevel.QUIET
    }
    doLast {
        logger.context.level = backupLoggerLevel
    }
}

..........

dependencies {
    def spockVersion = "1.3-groovy-2.4"
    def domaVersion = "2.24.0"
    def lombokVersion = "1.18.6"
    def errorproneVersion = "2.3.1"
    def powermockVersion = "2.0.0"
    def seleniumVersion = "3.13.0"
    def spotbugsVersion = "3.1.11"

    // dependency-management-plugin によりバージョン番号が自動で設定されるもの
    // Appendix F. Dependency versions ( https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/html/appendix-dependency-versions.html ) 参照
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-freemarker")
    implementation("org.springframework.boot:spring-boot-starter-mail")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    runtimeOnly("org.springframework.boot:spring-boot-devtools")
    implementation("org.springframework.session:spring-session-core")
    implementation("org.springframework.session:spring-session-jdbc")
    implementation("org.codehaus.janino:janino")
    implementation("org.flywaydb:flyway-core")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("org.springframework.security:spring-security-test")
    testImplementation("org.yaml:snakeyaml")

    // dependency-management-plugin によりバージョン番号が自動で設定されないもの、あるいは最新バージョンを指定したいもの
    implementation("com.integralblue:log4jdbc-spring-boot-starter:1.0.2")
    implementation("com.h2database:h2:1.4.192")
    implementation("com.github.rozidan:modelmapper-spring-boot-starter:1.0.0")
    implementation("com.google.guava:guava:27.1-jre")
    implementation("org.apache.commons:commons-lang3:3.8.1")
    testImplementation("org.dbunit:dbunit:2.6.0")
    testImplementation("org.assertj:assertj-core:3.12.2")
    testImplementation("org.spockframework:spock-core:${spockVersion}")
    testImplementation("org.spockframework:spock-spring:${spockVersion}")
    testImplementation("org.jsoup:jsoup:1.11.3")
    testImplementation("com.icegreen:greenmail:1.5.10")

    // for lombok
    annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
    compileOnly("org.projectlombok:lombok:${lombokVersion}")

    // for Doma
    annotationProcessor("org.seasar.doma:doma:${domaVersion}")
    implementation("org.seasar.doma:doma:${domaVersion}")
    domaGenRuntime("org.seasar.doma:doma-gen:${domaVersion}")
    domaGenRuntime("com.h2database:h2:1.4.192")

    // for Error Prone ( http://errorprone.info/ )
    errorprone("com.google.errorprone:error_prone_core:${errorproneVersion}")
    compileOnly("com.google.errorprone:error_prone_annotations:${errorproneVersion}")

    // PowerMock
    testImplementation("org.powermock:powermock-module-junit4:${powermockVersion}")
    testImplementation("org.powermock:powermock-api-mockito2:${powermockVersion}")

    // for Geb + Spock
    testImplementation("org.gebish:geb-spock:2.3.1")
    testImplementation("org.seleniumhq.selenium:selenium-chrome-driver:${seleniumVersion}")
    testImplementation("org.seleniumhq.selenium:selenium-firefox-driver:${seleniumVersion}")
    testImplementation("org.seleniumhq.selenium:selenium-support:${seleniumVersion}")
    testImplementation("org.seleniumhq.selenium:selenium-api:${seleniumVersion}")
    testImplementation("org.seleniumhq.selenium:selenium-remote-driver:${seleniumVersion}")

    // for SpotBugs
    compileOnly("com.github.spotbugs:spotbugs:${spotbugsVersion}")
    compileOnly("net.jcip:jcip-annotations:1.0")
    compileOnly("com.github.spotbugs:spotbugs-annotations:${spotbugsVersion}")
    testImplementation("com.google.code.findbugs:jsr305:3.0.2")
}
  • buildscript block の ext block 内の以下の点を変更します。
    • version "1.0.2-RELEASE"version "2.1.4-RELEASE" に変更します。今回から Spring Boot のバージョンに合わせます。
    • mainClass = "ksbysample.webapp.bootnpmgeb.Application" を削除します。
  • plugins block の以下の点を変更します。
    • id "org.springframework.boot" version "2.0.4.RELEASE"id "org.springframework.boot" version "2.1.4.RELEASE"
    • id "io.spring.dependency-management" version "1.0.6.RELEASE"id "io.spring.dependency-management" version "1.0.7.RELEASE"
    • id "com.moowork.node" version "1.2.0"id "com.moowork.node" version "1.3.1"
    • id "com.gorylenko.gradle-git-properties" version "1.5.1"id "com.gorylenko.gradle-git-properties" version "2.0.0"
  • configurations block に以下の2行を追加します。
    • testAnnotationProcessor.extendsFrom annotationProcessor
    • testImplementation.extendsFrom compileOnly
  • spotbugs block 内で toolVersion = "3.1.3"toolVersion = "3.1.11" に変更します。
  • pmdMain { ... } を追加します。
  • dependencies block の以下の点を変更します。
    • def spockVersion = "1.1-groovy-2.4"def spockVersion = "1.3-groovy-2.4"Geb が依存している groovy のバージョンが 2.4 なので、2.5 ではなく 2.4 にします)
    • def domaVersion = "2.19.2"def domaVersion = "2.24.0"
    • def lombokVersion = "1.18.0"def lombokVersion = "1.18.6"
    • def powermockVersion = "2.0.0-beta.5"def powermockVersion = "2.0.0"
    • def spotbugsVersion = "3.1.3"def spotbugsVersion = "3.1.11"
    • implementation("org.springframework.boot:spring-boot-starter-thymeleaf") に書いていた exclude group: "org.codehaus.groovy", module: "groovy" を削除します。
    • testImplementation("org.mockito:mockito-core") を削除します。
    • implementation("org.flywaydb:flyway-core:5.1.4")implementation("org.flywaydb:flyway-core:5.2.4")
    • implementation("com.google.guava:guava:25.1-jre")implementation("com.google.guava:guava:27.1-jre")
    • implementation("org.apache.commons:commons-lang3:3.7")implementation("org.apache.commons:commons-lang3:3.8.1")
    • testImplementation("org.dbunit:dbunit:2.5.4")testImplementation("org.dbunit:dbunit:2.6.0")
    • testImplementation("org.assertj:assertj-core:3.10.0")testImplementation("org.assertj:assertj-core:3.12.2")
    • testImplementation("com.icegreen:greenmail:1.5.7")testImplementation("com.icegreen:greenmail:1.5.10")
    • testImplementation("org.gebish:geb-spock:2.1")testImplementation("org.gebish:geb-spock:2.3.1")

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、特にエラーは出ずに更新されました。

src/main/java/ksbysample/webapp/bootnpmgeb/config/ApplicationConfig.java の以下の点も変更します。

    @Bean
    public Validator mvcValidator() {
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(this.messageSource);
        return localValidatorFactoryBean;
    }
  • public Validator mvcValidator()public Validator validator() に変更します。

clean タスク実行 → Rebuild Project 実行 → build タスク実行をしてみると、テストが大量に失敗しました。

f:id:ksby:20190414110553p:plain (.....途中省略.....) f:id:ksby:20190414110700p:plain

エラーの原因を調べるために Project Tool Window で src/test/groovy/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample''」を選択してテストを実行してみると以下のエラーメッセージが出ていました。Spring Session の AutoConfiguration クラス(org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration)で定義されている sessionEventHttpSessionListenerAdapter Bean が原因で BeanDefinitionOverrideException が発生しているとのこと。

  • Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'sessionEventHttpSessionListenerAdapter' defined in class path resource [org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration; factoryMethodName=sessionEventHttpSessionListenerAdapter; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration.class]] for bean 'sessionEventHttpSessionListenerAdapter': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; factoryMethodName=sessionEventHttpSessionListenerAdapter; initMethodName=null; destroyMethodName=(inferred); defined in org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration] bound.

自分で定義していない Bean の override 定義はさすがに解消しようがないので Spring Boot 2.1 Release Notes - Bean Overriding に記載されている spring.main.allow-bean-definition-overriding=true の設定を application.properties に記述することにします。application.properties の内容は以下のようになります。

doma.dialect=org.seasar.doma.jdbc.dialect.H2Dialect

management.endpoints.web.exposure.include=health,info,loggers,shutdown,threaddump
management.endpoint.shutdown.enabled=true

spring.datasource.hikari.jdbc-url=jdbc:h2:mem:bootnpmgebdb
spring.datasource.hikari.username=sa
spring.datasource.hikari.password=
spring.datasource.hikari.driver-class-name=org.h2.Driver
spring.datasource.hikari.leak-detection-threshold=5000
spring.datasource.hikari.register-mbeans=true

spring.freemarker.cache=true
spring.freemarker.settings.number_format=computer
spring.freemarker.charset=UTF-8
spring.freemarker.enabled=false
spring.freemarker.prefer-file-system-access=false

spring.main.allow-bean-definition-overriding=true

spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=embedded
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-h2.sql
spring.session.jdbc.table-name=SPRING_SESSION

spring.thymeleaf.mode=HTML

logging.level.root=INFO
logging.level.org.seasar.doma=ERROR

再度 clean タスク実行 → Rebuild Project 実行 → build タスク実行をすると、今度は BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190414114525p:plain

Tomcat を手動起動してから gebTest タスクを実行すると、こちらも BUILD SUCCESSFUL のメッセージが出力されました。これまで gebTest タスクの時は gradle-processes plugin で Tomcat自動起動・停止させていましたが、なくなると意外に不便ですね。。。

f:id:ksby:20190414115839p:plain

Headless モードを解除してブラウザを表示させて gebTest タスクを実行してみましたが、画面の表示等も特に問題はありませんでした。

履歴

2019/04/14
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その81 )( eslint を 4.19.1 → 5.16.0 へ、windows-build-tools を 3.1.0 → 5.1.0 へ、jest を 23.4.1 → 24.7.1 へ、postcss-cli を 4.1.1 → 6.1.2 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その80 )( nodist を 0.8.8 → 0.9.1 へ、Node.js を 8.11.4 → 10.15.3 へ、npm を 6.2.0-next.1 → 6.9.0 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • eslint を 4.19.1 → 5.16.0 へ、windows-build-tools を 3.1.0 → 5.1.0 へ、jest を 23.4.1 → 24.7.1 へ、postcss-cli を 4.1.1 → 6.1.2 へバージョンアップします。

参照したサイト・書籍

  1. eslint-config-airbnb-base
    https://www.npmjs.com/package/eslint-config-airbnb-base

目次

  1. eslint-config-airbnb-base を 13.0.0 → 13.1.0 へ、eslint を 4.19.1 → 5.16.0 へバージョンアップする
  2. windows-build-tools を 3.1.0 → 5.1.0 へバージョンアップする
  3. jest を 23.4.1 → 24.7.1 へバージョンアップする
  4. postcss-cli を 4.1.1 → 6.1.2 へバージョンアップする
  5. 最後に各種コマンドや build で問題がないか確認する

手順

eslint-config-airbnb-base を 13.0.0 → 13.1.0 へ、eslint を 4.19.1 → 5.16.0 へバージョンアップする

以下のコマンドを実行して eslint-config-airbnb-base を 13.1.0 へバージョンアップします。

  • npm info "eslint-config-airbnb-base@13.1.0" peerDependencies
  • npx install-peerdeps --dev eslint-config-airbnb-base@13.1.0

f:id:ksby:20190413151400p:plain

以下のコマンドも実行して eslint 関連のモジュールを最新のバージョンにします。

  • npm install --save-dev acorn@6.1.1
  • npm install --save-dev eslint@5.16.0
  • npm install --save-dev eslint-config-prettier@4.1.0
  • npm install --save-dev eslint-loader@2.1.2
  • npm install --save-dev eslint-plugin-import@2.16.0
  • npm install --save-dev eslint-plugin-prettier@3.0.1

npm test コマンドを実行するとテストは全て成功し、

f:id:ksby:20190413154129p:plain (.....途中省略.....) f:id:ksby:20190413154241p:plain

npm run build コマンドも特にエラーは出ずに終了しました。

f:id:ksby:20190413154347p:plain

windows-build-tools を 3.1.0 → 5.1.0 へバージョンアップする

管理者モードで Powershell を起動した後、以下のコマンドを実行します。install だけだとなぜか先に進まなかったので uninstall してから install するようにしました。

  • npm uninstall --global --production windows-build-tools
  • npm install --global --production windows-build-tools@5.1.0

f:id:ksby:20190413160951p:plain

jest を 23.4.1 → 24.7.1 へバージョンアップする

以下のコマンドを実行します。

  • npm install --save-dev jest@24.7.1
  • npm install --save-dev jest-html-reporter@2.5.0

レポートファイルを削除したいので最初に gradle から clean タスクを実行しておきます。npm test コマンドを実行するとテストは全て成功しました。

f:id:ksby:20190413162331p:plain

レポートファイルは build/reports/jest/jest-html-reporter.html に生成されており、開くと以下のように表示されます。

f:id:ksby:20190413162703p:plain

postcss-cli を 4.1.1 → 6.1.2 へバージョンアップする

以下のコマンドを実行します。

  • npm install --save-dev postcss-cli@6.1.2

以前 は画面の表示が崩れたと書きましたが、今回バージョンアップ後に原因を確認したところ common.min.css が出来ずに common.css だけが作成されて、common.css の中は minimize されているという結果だったからでした。src/main/resources/templates/web/common/fragments.html で読み込んでいるファイルを common.min.css → common.css に修正すると画面が正常に表示されるようになりました。

最後に各種コマンドや build で問題がないか確認する

最後にコマンド、build で問題がないか一通り確認します。

npm test コマンドは問題ありませんでした。

f:id:ksby:20190413204229p:plain (.....途中省略.....) f:id:ksby:20190413204401p:plain

npm run build コマンドも問題ありません。

f:id:ksby:20190413204538p:plain

clean タスク実行 → Rebuild Project 実行 → build タスク実行も問題ありません。

f:id:ksby:20190413205010p:plain

gebTest タスクも問題ありませんでした。

f:id:ksby:20190413205421p:plain

IntelliJ IDEA の「Settings」ダイアログを開いて「Language & Frameworks」-「Node.js and NPM」を表示し、バージョンアップ後の状態も記載しておきます。eslint-plugin-import、prettier、webpack がもう新バージョンが出ていますが、今はバージョンアップしません。

f:id:ksby:20190413205636p:plain f:id:ksby:20190413205714p:plain

次は Spring Boot や Java 側のモジュールをバージョンアップします。

履歴

2019/04/13
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その80 )( nodist を 0.8.8 → 0.9.1 へ、Node.js を 8.11.4 → 10.15.3 へ、npm を 6.2.0-next.1 → 6.9.0 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その79 )( webdriver-binaries-gradle-plugin を利用して WebDriver を個別にダウンロード不要にする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • nodist を 0.8.8 → 0.9.1 へ、Node.js を 8.11.4 → 10.15.3 へ、npm を 6.2.0-next.1 → 6.9.0 へバージョンアップします。
    • また npm でインストールしているモジュールを一部を除き最新のバージョンにします。

参照したサイト・書籍

  1. nullivex/nodist
    https://github.com/nullivex/nodist

目次

  1. まずは現在の状況を確認する
  2. nodist を 0.8.8 → 0.9.1 へバージョンアップする
  3. Node.js を 10.15.3 へ、npm を 6.9.0 へバージョンアップする
  4. モジュールを最新のバージョンにする

手順

まずは現在の状況を確認する

現在のバージョンは nodist が 0.8.8、Node.js が 8.11.4、npm が 6.2.0-next.1 です。

f:id:ksby:20190412074854p:plain

nodist を 0.8.8 → 0.9.1 へバージョンアップする

https://github.com/nullivex/nodist/releases から NodistSetup-v0.9.1.exe をダウンロードし、実行します。

  1. 「Welcome to Nodist Setup」画面が表示されます。「Next >」ボタンをクリックします。
  2. 「License Agreement」画面が表示されます。「I Agree」ボタンをクリックします。
  3. 「Choose Install Location」画面が表示されます。「Destination Folder」に 0.8.8 をインストールした時の D:\Nodist\ が表示されているので、そのまま「Install」ボタンをクリックします。
  4. 「Installing」画面が表示されてインストールが実行されます。
  5. 「Completing Nodist Setup」画面が表示されます。「Finish」ボタンをクリックします。

インストールが完了すると nodist が 0.9.1 になりますが、Node.js も 11.13.0 になりました。npm は前と変わらず 6.2.0-next.1 のままでした。

f:id:ksby:20190412211413p:plain

Node.js を 10.15.3 へ、npm を 6.9.0 へバージョンアップする

https://nodejs.org/ja/ を見ると Node.js の推奨版は 10.15.3 LTS でした。

f:id:ksby:20190412212046p:plain

Node.js は nodist をバージョンアップした時に 11.13.0 になっていますので 10.15.3 へバージョンダウンします。

f:id:ksby:20190412212612p:plain

npm の最新バージョンは https://github.com/npm/cli/releases を見ると 6.9.0 でした。

f:id:ksby:20190412213459p:plain

6.9.0 にバージョンアップします。

f:id:ksby:20190412213048p:plain

モジュールを最新のバージョンにする

バージョンアップ可能なモジュールを確認します。IntelliJ IDEA のメインメニューから「File」-「Settings...」を選択して「Settings」ダイアログを開き、画面左側で「Language & Frameworks」-「Node.js and NPM」を選択します。

画面右側にモジュールの一覧と現行バージョン、最新バージョン一覧が表示されます。

f:id:ksby:20190412213859p:plain f:id:ksby:20190412213936p:plain

今回は以下の方針でバージョンアップします。

  • admin-lte、bootstrap、ionicons は現行のまま。
  • mobx、mobx-utils は少し触ってみただけなのでバージョンアップしない。
  • eslint、jest + widows-build-tools、postcss-cli は別に章を分けてバージョンアップする。ただし postcss-cli以前 正常にバージョンアップできなかったのでしない可能性あり。
  • バージョンアップは npm update ではなく npm install --save-dev autoprefixer@8.0.0(package.json の dependencies に記載されているものは --save、devDependencies に記載されているものは --save-dev にする) のようにバージョンを指定しながらバージョンアップする。
  • 1つずつ上からバージョンアップする。関連しそうなところを動作確認しながら進める。
  • @vue/cli は boot-npm-geb-sample プロジェクトでは使用していないので、ここではバージョンアップしない。

特に問題がでなければ画面キャプチャは撮りません。

  • npm install --save-dev autoprefixer@9.5.1
  • npm install --save-dev browser-sync@2.26.3
  • npm install --save-dev cssnano@4.1.10
  • npm install --save-dev http-proxy-middleware@0.19.1
  • npm install --save jquery@3.4.0
  • npm install --save-dev jquery-mockjax@2.5.0
  • npm install --save-dev nock@10.0.6
  • npm install --save-dev npm-run-all@4.1.5
  • npm install --save-dev prettier@1.16.4
  • npm install --save-dev prettier-webpack-plugin@1.2.0
  • npm install --save-dev rimraf@2.6.3
  • npm install --save-dev stylelint@9.10.1
  • npm install --save-dev uglifyjs-webpack-plugin@2.1.2
  • npm install --save-dev webpack@4.29.6
  • npm install --save-dev webpack-cli@3.3.0
  • npm install --save-dev xhr-mock@2.4.1

コマンドラインから npm test コマンドを実行すると、かなりのテストが失敗しました。

f:id:ksby:20190412225750p:plain f:id:ksby:20190412225848p:plain (.....途中省略.....) f:id:ksby:20190412230017p:plain

実際に失敗したのは以下のテストで(IntelliJ IDEA から Jest のテストを実行しています)、xhr-mock が原因でした。

f:id:ksby:20190412230346p:plain

失敗しているテストを以下のように修正します。

  • xhrmock.setup();xhrmock.default.setup(); に変更します。
  • xhrmock.teardown();xhrmock.default.teardown(); に変更します。
  • xhrmock.getxhrmock.default.get に変更します。
  • timeout のテストは https://www.npmjs.com/package/xhr-mock#simulate-a-timeout を参考に xhrmock.default.get(..., (req, res) => { return res.timeout(true); });xhrmock.default.get(..., () => new Promise(() => {})); に変更します。

またプロジェクトの root ディレクトリ直下に node-tar-extract というディレクトリが作成されていたので削除します(このディレクトリがいつ作成されたのか分かりませんでした)。

再度 npm test コマンドを実行すると、今度は全てのテストが成功しました。

f:id:ksby:20190413005917p:plain

npm run build コマンドも特にエラーは出ずに終了しました。

f:id:ksby:20190413010234p:plain

clean タスク実行 → Rebuild Project 実行 → build タスク実行は問題なく BUILD SUCCESSFUL のメッセージが出力されて成功し、

f:id:ksby:20190413010736p:plain

gebTest タスクも BUILD SUCCESSFUL のメッセージが出力されて成功しました。

f:id:ksby:20190413011318p:plain

履歴

2019/04/13
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その79 )( webdriver-binaries-gradle-plugin を利用して WebDriver の個別ダウンロードを不要にする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その78 )( PMD を 6.5.0 → 6.6.0 へバージョンアップする+gradle-processes を導入する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Selenium WebDriver の実行ファイル(exe)を今は個別にダウンロードしたものを D:/geckodriver/0.19.0/geckodriver.exeD:/chromedriver/2.40/chromedriver.exe に配置して利用していますが、webdriver-binaries-gradle-plugin という Gradle の Plugin を利用することでダウンロードしなくてもよい方法を見つけたので、その方法に切り替えます。
    • ついでに今回から何回かに分けて使用しているフレームワークやライブラリを最新版にバージョンアップします。

参照したサイト・書籍

  1. Learn Geb + Spock : The best of breed solution for all your UI automation needs
    https://medium.com/automationschool/geb-spock-the-best-of-breed-solution-for-all-your-ui-automation-needs-94f01c998f18

  2. AutomationSchool/geb-and-spock-automation-examples
    https://github.com/AutomationSchool/geb-and-spock-automation-examples

  3. erdi/webdriver-binaries-gradle-plugin
    https://github.com/erdi/webdriver-binaries-gradle-plugin

  4. ChromeDriver - WebDriver for Chrome
    http://chromedriver.chromium.org/downloads

  5. mozilla/geckodriver
    https://github.com/mozilla/geckodriver

目次

  1. まずは現在の状況を確認する
  2. build.gradle を変更する
  3. GebConfig.groovy を変更する
  4. 動作確認

手順

まずは現在の状況を確認する

clean タスク実行 → Rebuild Project 実行 → build タスク実行は問題なく BUILD SUCCESSFUL のメッセージが出力されて成功します。

f:id:ksby:20190412055738p:plain

また Chrome のバージョンが 73.0.3683.103 で、

f:id:ksby:20190412060020p:plain

Firefox のバージョンが 66.0.3 ですが、

f:id:ksby:20190412060205p:plain

gebTest タスクを実行すると chromeTest タスクは成功しますが firefoxTest タスクは全てのテストが失敗します。ダウンロードしている geckodriver が今の Firefox に合っていないようです。

f:id:ksby:20190412060810p:plain (.....途中省略.....) f:id:ksby:20190412060904p:plain

build.gradle を変更する

geb-and-spock-automation-examples/twitter-app-ui-automation/build.gradleerdi/webdriver-binaries-gradle-plugin を参考にして build.gradle を以下のように変更します。

plugins {
    ..........
    id "com.energizedwork.webdriver-binaries" version "1.4"
}

..........

webdriverBinaries {
    chromedriver "73.0.3683.68"
    geckodriver "0.24.0"
}
def drivers = ["chrome", "firefox"]
drivers.each { driver ->
    task "${driver}Test"(type: Test) {
        // 前回実行時以降に何も更新されていなくても必ず実行する
        outputs.upToDateWhen { false }
        systemProperty "geb.env", driver
        exclude "ksbysample/**"
        dependsOn startServer
        finalizedBy stopServer
    }
}
task gebTest {
    dependsOn drivers.collect { tasks["${it}Test"] }
    enabled = false
}
  • plugins block に id "com.energizedwork.webdriver-binaries" version "1.4" を追加します。
  • webdriverBinaries { ... } を追加します。chromedriver のバージョンは ChromeDriver - WebDriver for Chrome で、geckodriver のバージョンは mozilla/geckodriver で確認して記述します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

GebConfig.groovy を変更する

import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions

//System.setProperty("webdriver.gecko.driver", "D:/geckodriver/0.24.0/geckodriver.bat")
//System.setProperty("webdriver.chrome.driver", "D:/chromedriver/73.0.3683.68/chromedriver.exe")
driver = {
    FirefoxOptions firefoxOptions = new FirefoxOptions()
    firefoxOptions.setHeadless(true)
    new FirefoxDriver(firefoxOptions)
}
baseUrl = "http://localhost:8080"
waiting {
    timeout = 15
}

environments {

    chrome {
        driver = {
            ChromeOptions chromeOptions = new ChromeOptions()
            chromeOptions.setHeadless(true)
            new ChromeDriver(chromeOptions)
        }
    }

    firefox {
        driver = {
            FirefoxOptions firefoxOptions = new FirefoxOptions()
            firefoxOptions.setHeadless(true)
            new FirefoxDriver(firefoxOptions)
        }
    }

}

IntelliJ IDEA から実行する時には個別の WebDriver と System.setProperty("webdriver.~.driver", ...) の設定が必要なので、削除はせずにコメントアウトだけしておきます。

動作確認

gebTest タスクを実行してみると今度は chromeTest, firefoxTest のどちらもエラーが出なくなりました。

f:id:ksby:20190412063541p:plain

GebConfig.groovy で setHeadless(true) の行をコメントアウトしてブラウザを表示して動作も見てみましたが、問題ないようです。

WebDriver のファイルを個別にダウンロードしてプロジェクトとは別のディレクトリに配置するのは避けたいと思っていたので、これは便利ですね!

履歴

2019/04/12
初版発行。
2019/04/13
* 最新の geckodriver、chromedriver をダウンロードしてディレクトリに配置する記述を追加した。
* System.setProperty("webdriver.gecko.driver", ...)System.setProperty("webdriver.chrome.driver", ...) の記述を削除するのではなくコメントアウトするよう修正した(削除すると IntelliJ IDEA からテストを実行できなくなるため)。
* D:/geckodriver/D:/chromedriver/ディレクトリを削除するという記述を削除した。

Spring Boot 2.0.x の Web アプリを 2.1.x へバージョンアップする ( 感想 )

記事一覧はこちらです。

  • Spring Boot 2.1 へのバージョンアップは現在使用している機能に関しては大きな変更はなかったのですが、

    • @ExtendWith(SpringExtension.class) が自動で付くようになったので、-Xlint:all オプションを付けた状態で JUnit 5 に切り替えていないと compileTestJava タスクで警告が出る。
    • gradle からテストを実行した時は何も出ないが、IntelliJ IDEA 上から実行すると Command line is too long. のエラーが表示される。

    のようにいつもと違ったところで警告やエラーが出た印象です。

  • 今回一番時間がかかったのは Spring Boot のバージョンアップよりも JUnit 5 への切り替えの方でした。JUnit 5 もバージョン 5.4 から BOM が提供されたり、junit-jupiter を指定すれば junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine の3つが依存関係に追加されるようになったり、Spring Boot 2.1 から @ExtendWith(SpringExtension.class) が自動で付与されるようになって記述する必要がなくなったり、とかなり導入しやすくなりました。テストも JUnit 4 と比較すると JUnit 5 の方が書きやすいですね。

    ただし Spock といまひとつ相性が良くありません。JUnit 5 の junit-vintage-engine 下だと Spock のテストが動かない場合がありました。Gradle だと Spock と JUnit 5 のテストのタスクを分けることが出来たので、とりあえずは問題ないかな。。。

  • JDK 11 へのバージョンアップは PowerMock と Groovy 周りで問題が発生しましたが、解決策も割と簡単に見つかって難しくはありませんでした。今回一番大変なところだろうと思っていたのですが、それ程でもありませんでした。error-prone も JDK 11 だと導入・設定が JDK 8 の頃と比べて簡単になった印象です。

さて、次に何を書くかを考えましょうか。。。