Gradle何も分からないけど、何とか動くようになったのでまとめておく。
[シェルスクリプトでE2Eテスト]
先日、自作したHTTPサーバーのE2Eテストを実装した。
シェルスクリプトと、Python製のHTTPクライアントであるhttpieを組み合わせている。
しかし、テストを実行する際には、ターミナルからスクリプトを手動で呼び出す必要があった。
[build.gradle.ktsでE2Eテスト]
手動で毎回テストを実行するのは面倒なので、gradleのビルドコマンドを実行した場合に自動的にE2Eテストが実行されるようにしたい。
▼Gradleタスクを定義する
Gradleのドキュメントを読んだけれどシェルスクリプトを実行する方法がよくわからなかったのでGoogleで検索したところ、Stack Overflowでやり方を見つけた。
以下のようにbuild.gradle.kts
ファイルにタスクを定義する。
task("e2etest") { doLast { exec { executable("./run_test.sh") } } }
しかし、gradle e2etest
とコマンドを実行してみると以下のように失敗してしまった。
$ gradle e2etest > Configure project : Kotlin Multiplatform Projects are an Alpha feature. See: https://kotlinlang.org/docs/reference/evolution/components-stability.html. To hide this message, add 'kotlin.mpp.stability.nowarn=true' to the Gradle properties. > Task :e2etest FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':e2etest'. > A problem occurred starting process 'command './run_test.sh''
もしかして、と思い確認してみるとテストスクリプトのファイルにパーミッションが不足していた。
$ ls -l | grep run_test -rw-r--r-- 1 akito staff 426 Dec 28 22:46 run_test.sh
以下のように実行権限を追加する。
$ chmod +x run_test.sh $ ls -l | grep run_test -rwxr-xr-x 1 akito staff 426 Dec 28 22:46 run_test.sh
これでタスクが実行できるようになった。
$ gradle e2etest > Configure project : Kotlin Multiplatform Projects are an Alpha feature. See: https://kotlinlang.org/docs/reference/evolution/components-stability.html. To hide this message, add 'kotlin.mpp.stability.nowarn=true' to the Gradle properties. > Task :e2etest ~ [INFO] TEST START ~ [INFO] started kttpd (PID: 29638) ~ [INFO] retrieve index.html ~ [INFO] http get index.html ~ [OK] request index.html get got response status code 200 ~ [OK] right index.html ~ [INFO] post simple form ~ [OK] right response ~ [INFO] stopped kttpd (PID: 29638) ~ [OK] TEST FINISHED Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/6.7.1/userguide/command_line_interface.html#sec:command_line_warnings BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed
▼ビルド時にE2Eテストを実行する
E2Eテストのタスクが定義できたので、ビルド時に自動的にこれを呼び出すようにしたい。
こちらのStack Overflowを見ると、dependsOn
とfinalizedBy
の2通りのやり方が紹介されていた。
dependsOn
を利用すると、あるタスクを実行する前に、依存関係にある別のタスクを必ず実行する、ということができるらしい。
実行順序だけ考えれば、今回「別のタスク」に該当するのはbuildタスクであるが、E2Eテストを実行する前に必ずビルドがしたいわけではない。ビルドを実行したあとで、必ずE2Eテストを実行したいのだ。
というわけでfinalizedBy
を採用し、build.gradle.kts
ファイルに以下のように追記する。
tasks["build"].finalizedBy("e2etest") tasks["nativeTestBinaries"].finalizedBy("e2etest")
1行目が、gradle buildコマンドでビルドを実行した場合にE2Eテストを自動で実行するための修正である。
2行目が、IntelliJでKotlin/Nativeプロジェクト全体をビルドした場合にE2Eテストを実行するための修正である。
IntelliJでKotlin/Nativeプロジェクトをビルドした場合、以下のGradleタスクが実行されていた。一番最後のネイティブテストを実行するタスクに続けて、E2Eテストを実行するようにしている。
> Task :compileKotlinNative > Task :linkDebugExecutableNative > Task :linkReleaseExecutableNative > Task :compileKotlinMetadata NO-SOURCE > Task :metadataMainClasses UP-TO-DATE > Task :metadataJar UP-TO-DATE > Task :assemble > Task :nativeMainBinaries > Task :nativeProcessResources NO-SOURCE > Task :nativeMainKlibrary > Task :compileTestKotlinNative > Task :linkDebugTestNative > Task :nativeTestBinaries