以下のsbt plugin作った話をします。
数日前のScalaMatsuri 2024の自分の発表の中で以下のような記述がありましたが
https://speakerdeck.com/xuwei_k/scalapuroziekutono-birudosu-du-gai-shan?slide=67
個々のtest時間を集計してみる
- 例えばscalatestだと
-oD
のようなオプションがあります- それをさらにいい感じに集計しないと・・・
- これだけでボトルネックわかるか?というと
ここに関して、真面目にしっかり計測というか集計したことがありませんでした。
正確には、sbtに関連する仕組みが存在しそうだったので、昔試したことがあったのですが、うまくいかなくてやめたことはありました。
testListeners
というkeyなど?
結論からいうと、sbt自体かscalatest側がバグっている気がする(おそらくsbt?)(forkしてる場合のみ?)のですが、まだ詳細追ってません。
sbt本体にもbug報告はしてないし、これ書いてる時点でかるく調べた限りは、他の人によるbug報告も存在しなそうです。
sbtのものは、テストが全部終わってからstartのeventなどが呼ばれて、実行時間が正しく取れない気がします。 sbtが吐き出すjunit reportにも実行時間があったはずですが、そちらも同様の問題があった気がします(うろ覚え)
実は他の手法でsbt単体で取得可能な仕組みが存在していたら、教えてください。
さて、他の方の 飛び入りカンファレンス
で、以下のような発表がありました。
OpenTelemetryの存在は知っていますが、それほど詳しくないのと、そもそも個人的には
「OpenTelemetry使うほど大掛かりでなくていいので、とりあえず遅い順に表示するだけとか、毎回のテストごとの変化は全自動で計測できなくてもいいから、1回のテスト実行で、相対的にどれが遅いのか?だけ知りたい」
と思ったので、OpenTelemetryの方ですごくしっかりやれば、そういう機能を含めて上位互換で綺麗に作れる可能性は普通にあるかもしれませんが、 一旦アイデアというか、scalatestのReporterの使い方だけ少し参考にさせてもらい、完全独自に作ってpublishしてみました。
実際のメインのファイルはreporterとsbt pluginのそれぞれ以下のファイルのみ
- https://github.com/xuwei-k/test-times-reporter/blob/581553464a0527099ee5bfe8bddcf2aaa328cc8a/reporter/src/main/scala/test_times/ScalaTestTestTimesReporter.scala
- https://github.com/xuwei-k/test-times-reporter/blob/581553464a0527099ee5bfe8bddcf2aaa328cc8a/plugin/src/main/scala/test_times/TestTimesPlugin.scala
以下、作った際の感想やポイントや解説です
- Chrome Traceか、GitHubで使えるmermaidのガントチャートで例のアレと同じように表示する機能も作っても良かったかもしれないが、一旦本当に最低限テキストで上位から表示する機能だけでリリースした
- 大抵はこの程度で十分感があるので
- https://xuwei-k.hatenablog.com/entry/2024/06/01/103536
- このblog書いた時点の対応versionなど
- sbtとは別にscalatestそのものにもjunit reportを出す仕組みがあって、もしかしたらそちらのxmlを独自にparseして集計をすれば、独自reporterは必要ない可能性はあるが、junit report若干size大きいし、細かいこと考えると独自に作ってしまった方が柔軟というか、大した手間ではない?ので作ってしまった
- xmlを独自にparseするコード書くのも、そこまで手間ではないとはいえ、結局書かないといけないし
- multi projectで全てを集計したい、reporterの依存をいい感じに自動で設定したい、などを考えると、それほど大したことはしてないですが、一応sbt pluginという形にしました
- OpenTelemetryでやる場合は、そちらで集計その他全部やってくれるでしょうけど(よくわかってない)、これは単純にsub projectごとにファイルに出して、その後にsbt pluginのtaskで集計、ということ
- scalatestの依存がユーザー側で追加されているどうか?の判断が、すごく無理やりになってしまったけど、もっといい案ないですか?
- taskひとつ実行するだけで、最近blogで何度か書いてるように
GITHUB_STEP_SUMMARY
に直接書き込む機能もつけました - 単体で別ファイルに書き出す機能もあるので、GitHub Actions以外の任意のCIやローカルでも使用は可能です
- ただし、出力の形式や、情報の種類がかなり限定的で固定ですが・・・(今後、どの程度柔軟に拡張するか?の詳細は未定)