かんがるーさんの日記

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

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その95 )( eslint を 6.8.0 → 7.32.0 へ、jest を 26.0.1 → 27.2.4 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その94 )( Node.js を 12.16.3 → 14.18.0 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • eslint を 6.8.0 → 7.32.0 へ、jest を 26.0.1 → 27.2.4 へバージョンアップします。

参照したサイト・書籍

  1. package.json に記載されているパッケージのバージョンアップ方法 【 npm-check-updates, outdated 】
    https://qiita.com/sugurutakahashi12345/items/df736ddaf65c244e1b4f

  2. Testing Asynchronous Code
    https://jestjs.io/docs/asynchronous

  3. axios - Cancellation
    https://github.com/axios/axios#cancellation

  4. Node.js v15に実装されたAbortController
    https://www.mitsue.co.jp/knowledge/blog/frontend/202012/14_0900.html

目次

  1. eslint を 6.8.0 → 7.32.0 へ、eslint-config-airbnb-base を 14.1.0 → 14.2.1 へ、eslint-config-prettier を 6.11.0 → 8.3.0 へ、eslint-plugin-import を 2.20.1 → 2.24.2 へ、eslint-plugin-prettier を 3.1.3 → 4.0.0 へバージョンアップする
  2. jest を 26.0.1 → 27.2.4 へバージョンアップする
  3. テストが失敗した原因を解消する
    1. The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string. Consider using the "jsdom" test environment.
    2. jQuery requires a window with a document
    3. Test functions cannot both take a 'done' callback and return something. Either use a 'done' callback, or return a promise.
    4. Jest has detected the following 2 open handles potentially keeping Jest from exiting:
    5. jest.setTimeout(...); を呼び出しても効かないようなので jest.config.json に testTimeout を設定する方法に切り替える

手順

eslint を 6.8.0 → 7.32.0 へ、eslint-config-airbnb-base を 14.1.0 → 14.2.1 へ、eslint-config-prettier を 6.11.0 → 8.3.0 へ、eslint-plugin-import を 2.20.1 → 2.24.2 へ、eslint-plugin-prettier を 3.1.3 → 4.0.0 へバージョンアップする

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

  • npm install --save-dev eslint@7.32.0
  • npm install --save-dev eslint-config-airbnb-base@14.2.1
  • npm install --save-dev eslint-config-prettier@8.3.0
  • npm install --save-dev eslint-plugin-import@2.24.2
  • npm install --save-dev eslint-plugin-prettier@4.0.0

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

f:id:ksby:20211001224700p:plain

npm run build コマンドも正常に終了しました。

f:id:ksby:20211001224838p:plain

途中で npx browserslist@latest --update-db のコマンドを実行するようメッセージが出力されているので、実行します。npm update は eslint 以外のモジュールもバージョンアップされるので(しかも必ずしも最新バージョンになる訳ではないらしい)実行しません。

f:id:ksby:20211001225203p:plain f:id:ksby:20211001225244p:plain

jest を 26.0.1 → 27.2.4 へバージョンアップする

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

  • npm install --save-dev jest@27.2.4
  • npm install --save-dev jest-html-reporter@3.4.1

レポートファイルを削除したいので最初に gradle から clean タスクを実行しておきます。

npm test コマンドを実行するとテストが大量に失敗するようになりました。。。

f:id:ksby:20211001233149p:plain

build/reports/jest/jest-html-reporter.html にレポートが出力されていますが、failed の赤ばかりです。

f:id:ksby:20211002000004p:plain

エラーになったテストで出力されているメッセージは全部で4つあり、1つ目は The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string. Consider using the "jsdom" test environment.

f:id:ksby:20211001234806p:plain

2つ目は jQuery requires a window with a document

f:id:ksby:20211001235051p:plain

3つ目は Test functions cannot both take a 'done' callback and return something. Either use a 'done' callback, or return a promise.

f:id:ksby:20211001235235p:plain

4つ目は Jest has detected the following 2 open handles potentially keeping Jest from exiting:

f:id:ksby:20211001235442p:plain

テストが失敗した原因を解消する

The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string. Consider using the "jsdom" test environment.

エラーメッセージに出力されている https://jestjs.io/docs/configuration#testenvironment-string を見ると The test environment that will be used for testing. The default environment in Jest is a Node.js environment. If you are building a web app, you can use a browser-like environment through jsdom instead. という記述があり、テストファイルの先頭に @jest-environment docblock を追加して @jest-environment jsdom を記述すれば解決するようですが、さすがに各テストファイルに記述するのは避けたいところです。

jest.config.json"testEnvironment": "jsdom", を追加することにします。

{
  "coverageDirectory": "build/reports/jest",
  "moduleDirectories": [
    "node_modules",
    "src/main/assets/js"
  ],
  "testEnvironment": "jsdom",
  "reporters": [
    "default",
    [
      "./node_modules/jest-html-reporter",
      {
        "pageTitle": "Test Report"
      }
    ]
  ]
}

また Jest 27: New Defaults for Jest, 2021 editionFor this reason, we are changing the default test environment from "jsdom" to "node". という記述がありました。For this reason の前の文章を読むと jsdom はパフォーマンス・オーバーヘッドがあるので default を node に変更したとのこと。今後は必要なテストだけテストファイルの先頭に @jest-environment docblock を追加する方式にした方が良いのでしょう。

jQuery requires a window with a document

testEnvironment を jsdom に変更したら出力されなくなりました。

Test functions cannot both take a 'done' callback and return something. Either use a 'done' callback, or return a promise.

https://jestjs.io/blog/2020/05/05/jest-26#other-breaking-changes-in-jest-26[jest-circus] Fail tests if a test takes a done callback and have return value という記述がありました。

done callback を使っているとテストが失敗するようになったことは分かりましたが、これだけでは対応方法が分かりません。他に参考になるものがないか調べてみると Done.fail function is not working の中に Testing Asynchronous Code へのリンクがありました。このページに対応方法が記載されています。

リンク先の記述に従って修正すると以下のコードの場合には、

  test("Nock で 500 を返すと catch の方で処理される", async (done) => {
    nock("http://api.openweathermap.org")
      .get(/^\/data\/2\.5\/weather/)
      .reply(500);

    await openWeatherMapHelper
      .getCurrentWeatherDataByCityName("Tokyo")
      .then((response) => {
        done.fail("then に処理が来たらエラー");
      })
      .catch((e) => {
        expect(e.response.status).toBe(500);
      });

    // test("...", async done => { ...}); と done を記述している場合には、テストの最後で done(); を呼び出さないと
    // 5秒待機した後、
    // Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
    // のエラーメッセージを表示してテストが失敗する
    // ※https://facebook.github.io/jest/docs/en/asynchronous.html#callbacks 参照
    done();
  });

async/await を取り除いて Promise を返すようにするか(Promise を返せば Jest は Promise が完了するまで待つとのこと)、

  test("Nock で 500 を返すと catch の方で処理される", () => {
    expect.assertions(1);

    nock("http://api.openweathermap.org")
      .get(/^\/data\/2\.5\/weather/)
      .reply(500);

    return openWeatherMapHelper
      .getCurrentWeatherDataByCityName("Tokyo")
      .catch(e => expect(e.response.status).toBe(500));
  });

async/await を残すならば try...catch で以下のように記述すればテストが成功するようになります。

  test("Nock で 500 を返すと catch の方で処理される", async () => {
    expect.assertions(1);

    nock("http://api.openweathermap.org")
      .get(/^\/data\/2\.5\/weather/)
      .reply(500);

    try {
      await openWeatherMapHelper.getCurrentWeatherDataByCityName("Tokyo");
    } catch (e) {
      expect(e.response.status).toBe(500);
    }
  });

今回は後者の async/await を残して try...catch で対応することにします。

  • async (done)async () に変更する。
  • done(); あるいは done.~ を呼び出している箇所を削除する。
  • テストの最初に expect.assertions(1); を記述する(assertions メソッドに渡す数字はテストで expect が呼び出される回数を指定する)。https://jestjs.io/docs/expect#expectassertionsnumber を読むと async を付けたテストメソッドの場合、きちんとテストが実行されているのかを確認するために expect.assertions を書いた方が良いらしい。
  • await を付けて呼び出しているところを、await を取り除いて try...catch で囲む記述に変更する。

Jest has detected the following 2 open handles potentially keeping Jest from exiting:

package.json で jest を実行するコマンドに --detectOpenHandles オプションを付けているのでテスト終了時にオープンされたままのハンドラが検知・出力されるのですが、以前から付けていて Jest 27 にバージョンアップされたらこれまで検知されていなかったものが検知されるようになったようです。

  "scripts": {
    "test": "run-s prettier:format prettier:format-test jest",
    "jest": "jest --config=jest.config.json --coverage --runInBand --detectOpenHandles",
    ..........

axios のリクエストを cancel する方法が https://github.com/axios/axios#cancellation に記述されており、これを使えば解消しそうな気がするのですが、うまく実装できません。。。 テストは成功しているので、今回は特に何もしないことにします。

また https://jestjs.io/docs/cli#--detectopenhandles によると --detectOpenHandlesデバッグ時のみ使用するよう書かれていたので、テストが並列で実行されなくなる --runInBand オプションと合わせて外すことにします。

  "scripts": {
    "test": "run-s prettier:format prettier:format-test jest",
    "jest": "jest --config=jest.config.json --coverage",
    "jest:debug": "jest --config=jest.config.json --coverage --runInBand --detectOpenHandles",
    ..........

jest.setTimeout(...); を呼び出しても効かないようなので jest.config.json に testTimeout を設定する方法に切り替える

上記4つの調査でいろいろ試している時に気づいたのですが、テストメソッド内で jest.setTimeout(30000); を呼び出しても 5秒経過するとテストがエラーになりました。jest.config.json"testTimeout": 30000, を設定すれば有効になるようなので、こちらの設定に切り替えます。

{
  "coverageDirectory": "build/reports/jest",
  "moduleDirectories": [
    "node_modules",
    "src/main/assets/js"
  ],
  "testEnvironment": "jsdom",
  "testTimeout": 30000,
  "reporters": [
    "default",
    [
      "./node_modules/jest-html-reporter",
      {
        "pageTitle": "Test Report"
      }
    ]
  ]
}

npm test コマンドを実行すると A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. というメッセージが出力されますが、テストは全て成功するようになりました。

f:id:ksby:20211003182726p:plain

build/reports/jest/jest-html-reporter.html のレポートも passed の緑のみになっています。

f:id:ksby:20211003183047p:plain

履歴

2021/10/03
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その94 )( Node.js を 12.16.3 → 14.18.0 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その93 )( WebDriver を最新バージョンに上げる ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Node.js を 12.16.3 → 14.18.0 へバージョンアップします。npm は 6.14.5 のままです(npm 7 系は Node.js の 16.x から対応のようなので)。
    • これまで Node.js のバージョン管理ツールとして nodist を使用していましたが 30 Mar 2019 にリリースされた 0.9.1 でバージョンが止まっており、Node.js の 14.x 系へのバージョンアップもスムーズに出来ないようなのと、nvm-windows の 1.1.8 が2週間程前にちょうどリリースされたので、nvm-windows に切り替えることにします。
    • npm でインストールしているモジュールを一部を除き最新のバージョンにします。

参照したサイト・書籍

  1. 2020 年ではもう使えない Nodist はアンインストールする (Windows)
    https://zenn.dev/ymasaoka/articles/note-uninstall-nodish-windows

  2. coreybutler / nvm-windows
    https://github.com/coreybutler/nvm-windows

  3. node-gradle / gradle-node-plugin
    https://github.com/node-gradle/gradle-node-plugin

  4. Node.jsの新LTS版となる「Node.js 16」正式リリース。Apple M1チップ対応、JavaScriptエンジン「V8 9.0」搭載など新機能
    https://www.publickey1.jp/blog/21/nodejsltsnodejs_16apple_m1javascriptv8_90.html

    • Node.js は 16.x 系がリリースされていたはずと思っていたら、アクティブな LTS になるのはリリースから6ヶ月後の 10月下旬からでした。npm 7対応も 16.x からのようです。

目次

  1. まずは現在の状況を確認する
  2. nodist をアンインストールする
  3. nvm-windows をインストールして Node.js を 12.16.3 → 14.18.0 へバージョンアップする
  4. モジュールを最新のバージョンにする
  5. Gradle の npm-script 実行用のプラグインを com.moowork.node:1.3.1com.github.node-gradle.node:3.1.1 に変更する

手順

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

現在のバージョンは nodist が 0.9.1、Node.js が 12.16.3、npm が 6.14.5 です。

f:id:ksby:20210930105814p:plain

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

f:id:ksby:20210930235949p:plain

nodist をアンインストールする

2020 年ではもう使えない Nodist はアンインストールする (Windows) の記事を見つけたので、ここに記載されている手順でアンインストールします。

コントロールパネルの「プログラムと機能」の画面を開き、nodist を選択してコンテキストメニューを表示してから「アンインストールと変更」を選択します。

f:id:ksby:20210930224041p:plain

D:\Nodist にインストールしていましたが、アンインストール後もこのディレクトリが残っているので削除します。

C:\Users\<ユーザ名>\.npmrc のファイルを削除します。

C:\Users\root\AppData\Roaming\npm-cacheディレクトリを削除します。

コマンドプロンプトで実行を試みると、nodist、Node.js、npm の全てが実行できなくなっていることが確認できました。

f:id:ksby:20210930225014p:plain

nvm-windows をインストールして Node.js を 12.16.3 → 14.18.0 へバージョンアップする

https://github.com/coreybutler/nvm-windows/releases の「1.1.8 - Corepack」から nvm-setup.zip をダウンロードします。

ダウンロードしたファイルを解凍すると nvm-setup.exe が生成されるので実行します。

  1. 「Setup - NVM for Windows」画面が表示されるので、「I accept the agreement」を選択後「Next」ボタンをクリックします。
  2. 「Select Destination Location」画面が表示されるので、インストール先を D:\nvm に変更後「Next」ボタンをクリックします。
  3. 「Set Node.js Symlink」画面が表示されるので、D:\nodejs に変更後「Next」ボタンをクリックします。
  4. 「Ready to install」画面が表示されるので、「Install」ボタンをクリックします。
  5. 「Completing the NVM for Windows Setup Wizard」画面が表示されるので、「Finish」ボタンをクリックします。

インストール後に環境変数を確認すると NVM_HOME、NVM_SYMLINK の2つが追加されて、この2つの環境変数を参照するよう PATH に追加されていました。

1.1.8 で nvm install lts というコマンドが追加されており、実行すると自動で現在の LTS である 14.18.0 がインストールされます。素晴らしい!

f:id:ksby:20210930234559p:plain

nvm use 14.18.0 コマンドを実行するよう書かれているので実行します。。。が、エラーになる上に SJIS文字コードだとエラーメッセージが文字化けして読めません。

f:id:ksby:20210930234739p:plain

nvm use 14.18.0 > nvm.log でファイルに出力してから IntelliJ IDEA で確認してみると、exit status 1: この操作を実行するための十分な特権がありません。 というエラーメッセージでした。

コマンドプロンプトを「管理者として実行」で起動してから nvm use 14.18.0 コマンドを実行すると、正常に実行されました。

f:id:ksby:20210930235136p:plain

管理者として実行していないコマンドプロンプトに戻ってバージョンを確認すると、nvm が 1.1.8、Node.js が 14.18.0、npm が 6.14.5 になっていました。

f:id:ksby:20210930235635p:plain

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

バージョンアップ可能なモジュールを確認します。IntelliJ IDEA のメインメニューから「File」-「Settings...」を選択して「Settings」ダイアログを開き、画面左側で「Language & Frameworks」-「Node.js and NPM」を選択します。。。が、node、npm を認識していませんでした。後から気づきましたが、nvm use 14.18.0 コマンド実行後に IntelliJ IDEA を再起動し忘れているのが原因なので、手動で追加して認識させる必要はありませんでした。。。

f:id:ksby:20211001000613p:plain

手動で追加して認識させることにします。「Node interpreter」の右にある「...」ボタンをクリックします。

f:id:ksby:20211001001424p:plain

「Node interpreters」ダイアログが表示されるので、画面左上の「+」ボタンをクリックした後ドロップダウンメニューから「Add Local...」を選択します。

f:id:ksby:20211001001805p:plain

「Select Path」ダイアログが表示されるので、D:\nodejs\node.exe を選択して「OK」ボタンをクリックします。

f:id:ksby:20211001001843p:plain

D:\Nodist\... のパスが登録されていますが邪魔なので選択して「-」ボタンをクリックして削除します。

f:id:ksby:20211001002019p:plain

削除後「OK」ボタンをクリックしてダイアログを閉じて「Settings」ダイアログに戻ると、今度は画面右側にモジュールの一覧と現行バージョン、最新バージョン一覧が表示されました。

f:id:ksby:20211001002631p:plain f:id:ksby:20211001002736p:plain

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

  • admin-lte、bootstrap、ionicons は現行のまま。
  • mobx、mobx-utils は少し触ってみただけなのでバージョンアップしない。
  • eslint、jest、autoprefixer + cssnano + postcss-cli、prettier、stylelint + stylelint-config-standard、webpack + webpack-cli は別に章を分けてバージョンアップする。
  • バージョンアップは npm update ではなく npm install --save-dev autoprefixer@8.0.0(package.json の dependencies に記載されているものは --save、devDependencies に記載されているものは --save-dev にする) のようにバージョンを指定しながらバージョンアップする。
  • 1つずつ上からバージョンアップする。関連しそうなところを動作確認しながら進める。

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

  • npm install --save-dev acorn@8.5.0
  • npm install --save-dev axios@0.21.4
  • npm install --save-dev browser-sync@2.27.5
  • npm install --save-dev http-proxy-middleware@2.0.1
  • npm install --save-dev jquery@3.6.0
  • npm install --save-dev jquery-mockjax@2.6.0
  • npm install --save-dev nock@13.1.3

npm install コマンドを実行してから(npm scripts の postinstall の処理を実行するため) npm test コマンドを実行すると全てのテストが成功しました。

f:id:ksby:20211001010223p:plain

npm run build コマンドも正常に終了しました。

f:id:ksby:20211001012513p:plain

clean タスク実行 → Rebuild Project 実行 → build タスク実行は npmTest タスクでエラーになりました。

f:id:ksby:20211001012923p:plain

原因は nvm use 14.18.0 コマンド実行後に IntelliJ IDEA を再起動していないため、D:\nodejsディレクトリ(コマンド実行後に作成されるシンボリックリンク)を認識できていないからでした。

IntelliJ IDEA を再起動すれば認識されるはずですが、Gradle の npm-script 実行用のプラグインは cmd.exe を呼び出さなくてもよい https://github.com/node-gradle/gradle-node-plugin が出ているので、切り替えることにします。

Gradle の npm-script 実行用のプラグインcom.moowork.node:1.3.1com.github.node-gradle.node:3.1.1 に変更する

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

plugins {
    ..........
    id "com.github.node-gradle.node" version "3.1.1"
    ..........
}

..........

task npmTest(type: NpmTask) {
    args = ["test"]
}
task npmBuild(type: NpmTask) {
    args = ["run", "build"]
}
npmBuild.dependsOn npmTest
processResources.dependsOn npmBuild
  • plugins block の以下の点を変更します。
    • id "com.moowork.node" version "1.3.1"id "com.github.node-gradle.node" version "3.1.1" に変更します。
  • npmTest タスクの以下の点を変更します。
    • type を ExecNpmTask に変更します。
    • commandLine "cmd", "/c", "npm test >NUL 2>&1"args = ["test"] に変更します。
  • npmBuild タスクの以下の点を変更します。
    • type を ExecNpmTask に変更します。
    • commandLine "cmd", "/c", "npm run build >NUL 2>&1"args = ["run", "build"] に変更します。

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

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

f:id:ksby:20211001020304p:plain

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

f:id:ksby:20211001020845p:plain

今回は browser-sync と http-proxy-middleware をバージョンアップしたので npm run springboot で起動してみましたが特に問題なく起動しました。

f:id:ksby:20211001022513p:plain f:id:ksby:20211001022603p:plain

履歴

2021/10/01
初版発行。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その93 )( WebDriver を最新バージョンに上げる )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その92 )( http-proxy-middleware の createProxyMiddleware 関数の引数 context には Proxy させない URI を後に書く ) の続きです。

何回かに分けて boot-npm-geb-sample プロジェクトのモジュールやツールを 2021/10 時点の最新バージョンにします。IntelliJ IDEA は 2021.2.2、JDKEclipse Temurin 11.0.12+7 を使用します。

  • 今回の手順で確認できるのは以下の内容です。
    • WebDriver を最新バージョンに上げて動作するようにします。
    • 今回は SeleniumGeb は最新バージョンには上げません。Geb の最新バージョン 5.0 は Groovy 3、Spock 2 へのバージョンアップが必要なので、Gradle のバージョンアップをした後にバージョンアップします。

参照したサイト・書籍

目次

  1. WebDriver のバージョンを最新にする
  2. build タスクと gebTest タスク、及び IDEA から Geb のテストを実行した時の動作確認する

手順

WebDriver のバージョンを最新にする

動作確認をする前に ChromeFirefox のWebDriver を最新バージョンにします。Chrome の WebDriver は https://chromedriver.chromium.org/ を見ると Latest stable release は 94.0.4606.61、Firefox の WebDriver は https://github.com/mozilla/geckodriver/releases を見ると 0.30.0 でした。

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

webdriverBinaries {
    chromedriver "94.0.4606.61"
    geckodriver "0.30.0"
}
  • chromedriver "81.0.4044.69"chromedriver "94.0.4606.61" に変更します。
  • geckodriver "0.26.0"geckodriver "0.30.0" に変更します。

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

また chromedriver、geckodriver の exe もダウンロードして D:\chromedriver\94.0.4606.61D:\geckodriver\0.30.0 の下に配置した後、src/test/resources/GebConfig.groovy の以下の点を変更します。

//System.setProperty("webdriver.gecko.driver", "D:/geckodriver/0.30.0/geckodriver.bat")
//System.setProperty("webdriver.chrome.driver", "D:/chromedriver/94.0.4606.61/chromedriver.exe")
driver = {
    ..........
  • D:/geckodriver/0.26.0/geckodriver.batD:/geckodriver/0.30.0/geckodriver.bat に変更します。
  • D:/chromedriver/81.0.4044.69/chromedriver.exeD:/chromedriver/94.0.4606.61/chromedriver.exe に変更します。

build タスクと gebTest タスク、及び IDEA から Geb のテストを実行した時の動作確認する

clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと compileTestGroovy タスクで警告のメッセージが出ますが、BUILD SUCCESSFUL のメッセージが表示されます。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 へバージョンアップする) と同じ状況ですので、これは OK。

f:id:ksby:20210929192305p:plain

Web アプリを起動してから gebTest タスクを実行してみると、こちらも BUILD SUCCESSFUL のメッセージが表示されました。

f:id:ksby:20210929194325p:plain

次は IDEA から Geb のテストを実行してみます。src/test/resources/GebConfig.groovy の上に記述している WebDriver のパスの設定のコメントを解除してから、

System.setProperty("webdriver.gecko.driver", "D:/geckodriver/0.30.0/geckodriver.bat")
System.setProperty("webdriver.chrome.driver", "D:/chromedriver/94.0.4606.61/chromedriver.exe")
driver = {
    ChromeOptions chromeOptions = new ChromeOptions()
    new ChromeDriver(chromeOptions)
//    FirefoxOptions firefoxOptions = new FirefoxOptions()
//    new FirefoxDriver(firefoxOptions)
}

src/test/groovy/geb/gebspec/inquiry/InquiryTestSpec.groovy を開いてテストを実行します。

f:id:ksby:20210929194623p:plain

Chrome はすべてのテストが成功しました。

f:id:ksby:20210929194929p:plain

Firefox に切り替えてテストを実行すると、

System.setProperty("webdriver.gecko.driver", "D:/geckodriver/0.30.0/geckodriver.bat")
System.setProperty("webdriver.chrome.driver", "D:/chromedriver/94.0.4606.61/chromedriver.exe")
driver = {
//    ChromeOptions chromeOptions = new ChromeOptions()
//    new ChromeDriver(chromeOptions)
    FirefoxOptions firefoxOptions = new FirefoxOptions()
    new FirefoxDriver(firefoxOptions)
}

こちらもすべてのテストが成功しました。

f:id:ksby:20210929195413p:plain

履歴

2021/09/29
初版発行。

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その14 )( google_checks.xml に Record に関する定義を反映する+bootBuildImage タスクで Java 17 ベースの Docker Image を作成して動作確認する )

概要

記事一覧はこちらです。

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その13 )( Spring Boot を 2.5.4 → 2.5.5 へ、Eclipse Adoptium OpenJDK(Eclipse Temurin) を 11.0.12+7 → 17+35 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Java 17 にバージョンアップしたので、checkstyle の定義ファイル google_checks.xml にエラーが出るので未反映だった Record に関する定義を反映します。
    • bootBuildImage タスクを実行して Java 17 ベースの docker.io/library/ksbysample-webapp-lending:2.5.5 の Docker Image を作成して動作確認します。

参照したサイト・書籍

  1. checkstyle/checkstyle - checkstyle/src/main/resources/google_checks.xml
    https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml

  2. "network default: network.external.name is deprecated in favor of network.name"
    https://github.com/docker/compose-cli/issues/1856

目次

  1. google_checks.xml に Record に関する定義を反映する
  2. bootBuildImage タスクで Java 17 ベースの Docker Image を生成し動作確認する

手順

google_checks.xml に Record に関する定義を反映する

google_checks.xml から Record に関する定義を反映します。今回反映した内容を箇条書きで記述しておきます。

  • RECORD_DEF、RECORD_COMPONENT_DEF の記述が未反映の箇所に反映しました。
  • <module name="RecordComponentName">.....</module> を追加しました。
  • <module name="RecordTypeParameterName">.....</module> を追加しました。

clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると checkstyleMain タスクで何もログは出力されず、"BUILD SUCCESSFUL" のメッセージが出力されました。

f:id:ksby:20210929113541p:plain

bootBuildImage タスクで Java 17 ベースの Docker Image を生成し動作確認する

bootBuildImage タスクを実行して ksbysample-webapp-lending:2.5.5 の Docker Image を生成します。

https://github.com/bell-sw/Liberica/releases/download/17+35/bellsoft-jre17+35-linux-amd64.tar.gz がダウンロードされて BUILD SUCCESSFUL のメッセージが出力されました。bootBuildImage タスクも Java 17 対応されているようです。

f:id:ksby:20210929115624p:plain .......... f:id:ksby:20210929115743p:plain

docker-compose.app.yml を以下のように変更します。

  app:
    image: ksbysample-webapp-lending:2.5.5
    environment:
      - JAVA_TOOL_OPTIONS=-Dspring.profiles.active=product -Dlogging.appender=CONSOLE
      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
      - SPRING_MAIL_HOST=mail-server
      - SPRING_RABBITMQ_HOST=haproxy
    deploy:
      mode: replicated
      replicas: 3
    # entrypoint: /bin/bash
    # stdin_open: true
    # tty: true
  • image: ksbysample-webapp-lending:2.5.4image: ksbysample-webapp-lending:2.5.5 に変更します。

docker-compose -f docker-compose.mail.yml up -d コマンドを実行します。。。が、network default: network.external.name is deprecated in favor of network.name というメッセージが出力されていることに気づきました。

f:id:ksby:20210929131123p:plain

調べてみると https://github.com/docker/compose-cli/issues/1856 のことで、Docker Compose V2 から記述の仕方が変更になるようです。docker-compose -f docker-compose.mail.yml down を実行した後、docker-compose.mail.yml、docker-compose.app.yml の networks の記述を以下のように変更します。

networks:
  default:
    name: ksbysample-webapp-lending_default
    external: true
  • networks.default.external.name → networks.default.name に変更し、name と同じ階層に external: true を追加します。

docker-compose -f docker-compose.mail.yml up -ddocker-compose -f docker-compose.app.yml up -d コマンドを実行します。

f:id:ksby:20210929132750p:plain

http://localhost:8080/haproxy?stats にアクセスして全てのインスタンスが緑色になるまで待ちます。

f:id:ksby:20210929132919p:plain

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その11 )( Docker で複数の Tomcat を起動して動作確認する ) に書いてある手順で動作確認します(画面キャプチャは省略します)。

動作確認は特に問題ありませんでした。

docker-compose -f docker-compose.app.yml downdocker-compose -f docker-compose.mail.yml downdocker-compose down コマンドを実行してコンテナを停止します。

履歴

2021/09/29
初版発行。

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その13 )( Spring Boot を 2.5.4 → 2.5.5 へ、Eclipse Adoptium OpenJDK(Eclipse Temurin) を 11.0.12+7 → 17+35 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その12 )( build.gradle から --add-opens=.....=ALL-UNNAMED の記述を削除する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Java 17 に対応した Spring Boot 2.5.5. と、Eclipse Adoptium OpenJDK(Eclipse Temurin)の 17 がリリースされたので、バージョンアップします。

参照したサイト・書籍

目次

  1. Spring Boot を 2.5.4 → 2.5.5 へバージョンアップする
  2. Eclipse Adoptium OpenJDK(Eclipse Temurin) を 11.0.12+7 → 17+35 へバージョンアップする
  3. build タスク時に pmdMain タスクと test タスクで出力された警告を確認する
    1. WARNING: System::setSecurityManager will be removed in a future release
    2. OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

手順

Spring Boot を 2.5.4 → 2.5.5 へバージョンアップする

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

buildscript {
    ext {
        group "ksbysample"
        version "2.5.5"
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/release/" }
        gradlePluginPortal()
    }
    dependencies {
        // for doma-codegen-plugin
        classpath "org.postgresql:postgresql:42.2.24"
    }
}

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.5.5"
    id "io.spring.dependency-management" version "1.0.11.RELEASE"
    id "groovy"
    id "checkstyle"
    id "com.github.spotbugs" version "4.7.3"
    id "pmd"
    id "net.ltgt.errorprone" version "2.0.2"
    id "com.gorylenko.gradle-git-properties" version "2.3.1"
    id "org.seasar.doma.codegen" version "1.4.1"
}

..........

dependencyManagement {
    imports {
        // bomProperty に指定可能な property は以下の URL の BOM に記述がある
        // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.5.4/spring-boot-dependencies-2.5.4.pom
        mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) {
            // Spring Boot の BOM に定義されているバージョンから変更する場合には、ここに以下のように記述する
            // bomProperty "thymeleaf.version", "3.0.9.RELEASE"
        }
        mavenBom("org.junit:junit-bom:5.8.1")
    }
}

dependencies {
    def spockVersion = "2.0-groovy-3.0"
    def jdbcDriver = "org.postgresql:postgresql:42.2.24"
    def domaVersion = "2.49.0"
    def lombokVersion = "1.18.20"
    def errorproneVersion = "2.9.0"

    ..........

Spring Boot 2.5.5 へのバージョンアップとして以下の点を変更します。

  • buildscript block の以下の点を変更します。
    • version "2.5.4"version "2.5.5"
  • plugins block の以下の点を変更します。
    • id "org.springframework.boot" version "2.5.4"id "org.springframework.boot" version "2.5.5"

各種ライブラリのバージョンアップとして以下の点を変更します。

  • buildscript block の以下の点を変更します。
    • classpath "org.postgresql:postgresql:42.2.23"classpath "org.postgresql:postgresql:42.2.24"
  • dependencyManagement block の以下の点を変更します。
    • mavenBom("org.junit:junit-bom:5.7.2")mavenBom("org.junit:junit-bom:5.8.1")
  • dependencies block の以下の点を変更します。
    • def jdbcDriver = "org.postgresql:postgresql:42.2.23"def jdbcDriver = "org.postgresql:postgresql:42.2.24"
    • def domaVersion = "2.47.1"def domaVersion = "2.49.0"

Gradle Tool Window の左上にある「Reload All Gradle Projects」ボタンをクリックして更新します。

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

f:id:ksby:20210926132712p:plain

Eclipse Adoptium OpenJDK(Eclipse Temurin) を 11.0.12+7 → 17+35 へバージョンアップする

  1. IntelliJ IDEA を終了させます。

  2. https://adoptium.net/index.html から OpenJDK17-jdk_x64_windows_hotspot_17_35.msi をダウンロードします。

    f:id:ksby:20210926133106p:plain

  3. インストール時に削除されるかもしれないので D:\Java\jdk-11.0.12.7-hotspot → D:\Java\jdk-11.0.12.7-hotspotx にリネームします。

  4. インストーラーを実行して D:\java\jdk-17.0.0.35-hotspot へインストールした後、環境変数 JAVA_HOME のパスを D:\java\jdk-17.0.0.35-hotspot へ変更します。

    f:id:ksby:20210926133806p:plain

    コマンドプロンプトから java -version を実行し、17+35 に変更されていることを確認します。

    f:id:ksby:20210926134034p:plain

  5. D:\Java\jdk-11.0.12.7-hotspotx → D:\Java\jdk-11.0.12.7-hotspot に戻します。

  6. IntelliJ IDEA を起動します。

  7. 「Welcome to IntelliJ IDEA」ダイアログで ksbysample-webapp-lending プロジェクトを開いて、プロジェクトが使用する JDK を 11.0.12+7 に変更します。

  8. IntelliJ IDEA のメイン画面が開いたら、メニューから「File」-「Project Structure...」を選択します。

  9. 「Project Structure」ダイアログが表示されます。「Project SDK」で D:\Java\jdk-17.0.0.35-hotspot を選択します(なぜか2行表示されています)。

    f:id:ksby:20210926134643p:plain

  10. 「Experimental Feature Alert」のダイアログが表示されるので「Accept」ボタンをクリックします。

    f:id:ksby:20210926134821p:plain

  11. 「Project SDK」の「Edit」ボタンをクリックします。

    f:id:ksby:20210926134956p:plain

  12. 「Project Structure」ダイアログが表示されます。画面左側で「Platform Settings」-「SDKs」を選択して、中央のリストから「11.0.12.7」を選択した後、リストの上の「-」ボタンをクリックして削除します。

    f:id:ksby:20210926135118p:plain

  13. 中央のリストから「17」を選択した後、"17" → "17+35" へ変更します。

    f:id:ksby:20210926135259p:plain

  14. 「OK」ボタンをクリックして「Project Structure for New Projects」ダイアログを閉じます。

  15. メイン画面に戻ると画面右下に「Indexing...」の表示が出るので、終了するまで待ちます。

  16. build.gradle の sourceCompatibility、targetCompatibility の設定を JavaVersion.VERSION_17 に変更します。

    • sourceCompatibility = JavaVersion.VERSION_11sourceCompatibility = JavaVersion.VERSION_17
    • targetCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_17
  17. Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

  18. clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されますが、pmdMain タスクと test タスクで警告が出力されました。

    f:id:ksby:20210926140206p:plain

    pmdMain タスクで出力された警告は以下のものでした。

    • WARNING: A terminally deprecated method in java.lang.System has been called
    • WARNING: System::setSecurityManager has been called by edu.umd.cs.findbugs.ba.jsr305.TypeQualifierValue (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/com.github.spotbugs/spotbugs/4.4.0/83d0d8856de551bb4aa2f4b815a61b606c93acf/spotbugs-4.4.0.jar)
    • WARNING: Please consider reporting this to the maintainers of edu.umd.cs.findbugs.ba.jsr305.TypeQualifierValue
    • WARNING: System::setSecurityManager will be removed in a future release

    test タスクで出力された警告は以下のものでした。

    • OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

    調査は後回しにして先に進めます。

  19. Project Tool Window で src/test でコンテキストメニューを表示して「More Run/Debug」-「Run 'All Tests' with Coverage」を選択し、テストが全て成功することを確認します。

    f:id:ksby:20210926141718p:plain

build タスク時に pmdMain タスクと test タスクで出力された警告を確認する

WARNING: System::setSecurityManager will be removed in a future release

pmdMain タスクで出力された警告ですが、将来 Security Manager を廃止するために非推奨になっているためでした(https://openjdk.java.net/jeps/411 参照)。 ログを見ると spotbugs-4.4.0.jar で System::setSecurityManager が呼び出されているので PMD ではなく SpotBugs が原因でした。

SpotBugs は 4.4.1 がリリースされていたのでバージョンアップしてみましたが、警告が出力される状況は解消されなかったので、現時点では 4.4 のままとし SpotBugs の対応を待つことにします。

OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

以下の URL にこの警告に関する記述があり、

test タスク実行時の jvmArgs に -Xshare:off オプションを追加すれば警告が出力されないようにはできますが、気にするような警告ではないようなので、今は出力されたままにすることにします。

Java 17 は特にエラーも出ずに切り替えることができました。

ただし Lombok は現在使用している 1.18.20 ではまだ PLATFORM: JDK16 support added. 止まりで正式に Java 17 対応を表明してはいないので(https://projectlombok.org/changelog 参照)、Lombok を使うなら Java 17 の利用は Lombok の正式対応を待った方が良さそうです。

Gradle もまだ Java 17 には正式に対応していませんでした(https://github.com/gradle/gradle/issues/16857 参照)。7.3 で対応するそうです。

履歴

2021/09/26
初版発行。

IntelliJ IDEA を 2021.2.1 → 2021.2.2 へバージョンアップ

IntelliJ IDEA を 2021.2.1 → 2021.2.2 へバージョンアップする

IntelliJ IDEA の 2021.2.2 がリリースされているのでバージョンアップします。

※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。

  1. IntelliJ IDEA のメインメニューから「Help」-「Check for Updates...」を選択します。

  2. IntelliJ IDEA and Plugin Updates」ダイアログが表示されます。右下に「Update and Restart」ボタンが表示されていますので、「Update and Restart」ボタンをクリックします。

    f:id:ksby:20210926104303p:plain

  3. Plugin の update も表示されました。このまま「Update」ボタンをクリックします。

    f:id:ksby:20210926104344p:plain

  4. Patch がダウンロードされて IntelliJ IDEA が再起動します。

  5. IntelliJ IDEA が起動すると画面下部に「Indexing」のメッセージが表示されますので、終了するまで待機します。

  6. IntelliJ IDEA のメインメニューから「Help」-「About」を選択し、2021.2.2 へバージョンアップされていることを確認します。

  7. clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。

    f:id:ksby:20210926111534p:plain

  8. Project Tool Window で src/test でコンテキストメニューを表示して「More Run/Debug」-「Run 'All Tests' with Coverage」を選択し、テストが全て成功することを確認します。

    f:id:ksby:20210926111944p:plain

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その12 )( build.gradle から --add-opens=.....=ALL-UNNAMED の記述を削除する )

概要

記事一覧はこちらです。

Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その11 )( Docker で複数の Tomcat を起動して動作確認する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • build.gradle に不要になった -add-opens=.....=ALL-UNNAMED の記述が残っていたので削除します。

参照したサイト・書籍

目次

  1. build.gradle を変更する

手順

build.gradle を変更する

build.gradle を見直していたところ、以下の記述が残っていることに気づきました。今回のバージョンアップで groovy が 3系になって powermock も依存関係から削除しており、このオプションは不要になっているはずなので削除します。

// 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"
]

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

test {
    jvmArgs = jvmArgsForTask +
            ["-Dspring.profiles.active=unittest"]

    // for JUnit 5
    useJUnitPlatform()

    testLogging {
        afterSuite printTestCount
    }
}
  • def jvmArgsAddOpens = [ "--add-opens=java.base/java.io=ALL-UNNAMED", ... ] の記述を削除します。
  • test タスクの jvmArgs の記述から jvmArgsAddOpens + を削除します。

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

f:id:ksby:20210926094902p:plain

履歴

2021/09/26
初版発行。