「オタクが最新技術を追う LTイベント 2023春」における「JavaのテストカバレッジをSlackに投稿してみる」の登壇資料です。
■イベント情報 https://yumenosora.connpass.com/event/274863/
■今後のイベントについてはこちら https://yumenosora.connpass.com/
■虎の穴ラボ 採用サイト https://yumenosora.co.jp/tora-lab/
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.JavaのテストカバレッジをSlackに投稿してみる とらのあなラボ 鷺山
View Slide
Copyright © 2023 Toranoana Inc. All Rights Reserved.自己紹介 業務 ● とらのあな通販の開発 ○ バックエンドは Java ● サークル様向けシステム (リニューアル) ○ バックエンドは Kotlin 趣味 ● 旅行とサウナ ○ 先月ワーケーション制度を使って鹿児島に行ってきました ○ サウナ付きホテルに1週間滞在 ○ 朝サウナ ➔ 仕事 ➔ 夜サウナ
Copyright © 2023 Toranoana Inc. All Rights Reserved.アジェンダ ● 作ったモノの動作イメージ ● 作り方のご紹介 ○ 構成図 ○ 使用ライブラリ ○ スクリプトのコード ● まとめと感想 3
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.作ったモノの動作イメージ 4 各サブプロジェクトのカバレッジ プロジェクト全体のカバレッジ ※ ※C0カバレッジ: テストでカバーされた命令行数 ÷ すべての命令行数 (命令網羅率)
Copyright © 2023 Toranoana Inc. All Rights Reserved.5 構成図
Copyright © 2023 Toranoana Inc. All Rights Reserved.6 構成図 …① …② …③ …④ …⑤ 解説する順番
Copyright © 2023 Toranoana Inc. All Rights Reserved.7 構成図 gradle test や mvn test の実行➔ このとき、カバレッジ情報も 出力されるようにする ➔ カバレッジ計測ツールJaCoCoを 利用
Copyright © 2023 Toranoana Inc. All Rights Reserved.8 JaCoCo: Java向けカバレッジ計測ライブラリ ● Java Code Coverage Library ● テスト実行時にカバレッジを計測してくれる ● GradleやMavenで利用可能 ● 結果はHTML, XML, CSVなどの形式で出力可能 ▲HTML形式の出力例 (上記はJaCoCo自身のカバレッジ) https://www.jacoco.org/jacoco/trunk/coverage/より引用
Copyright © 2023 Toranoana Inc. All Rights Reserved.9 構成図 JaCoCoにより得られた カバレッジ情報を プロジェクトごとに集約
Copyright © 2023 Toranoana Inc. All Rights Reserved.10 JaCoCoの出力結果をプロジェクトごとに集約 ● JaCoCoのCSV形式の出力結果を使用 ● CSVファイルはプロジェクトごとに出力される ● CSVファイルは次のような構成になっている: ● 1列目: プロジェクト名 ● 2列目: パッケージ名 ● 3列目: クラス名 ● 4列目: テストでカバーされなかった命令行数 ● 5列目: テストでカバーされた命令行数 (6列目以降は今回使用しないため省略) クラスごとに 出力されている project1,com.example.project1,ClassA,250,250,…project1,com.example.project1,ClassB,200,300,…project1,com.example.project1,ClassC,100,400,…︙
Copyright © 2023 Toranoana Inc. All Rights Reserved.11 JaCoCoの出力結果をプロジェクトごとに集約 ● JaCoCoのCSV形式の出力結果を使用 ● CSVファイルはプロジェクトごとに出力される ● CSVファイルは次のような構成になっている: project1,com.example.project1,ClassA,250,250,…project1,com.example.project1,ClassB,200,300,…project1,com.example.project1,ClassC,100,400,…︙「5列目の総和」 ÷ 「4〜5列目の総和」で 各プロジェクトごとの C0カバレッジ※を算出できる ● 1列目: プロジェクト名 ● 2列目: パッケージ名 ● 3列目: クラス名 ● 4列目: テストでカバーされなかった命令行数 ● 5列目: テストでカバーされた命令行数 ※ C0カバレッジ= 「テストでカバーされた命令行数」 ÷ 「すべての命令行数」
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.#!/bin/bashprojects=('project1' 'project2' 'project3') # プロジェクト名のリスト# 入力したプロジェクトのC0カバレッジ情報を返す関数get_coverage() {local file="build/reports/jacoco/test/jacocoTestReport.csv"if [ -f "$1/$file" ]; thenlocal covered=$(awk -F ',' '{ it += $5 } END { print it }' "$1/$file")local instructions=$(awk -F ',' '{ it += $4 + $5 } END { print it }' "$1/$file")echo "$1,$covered,$instructions"elseecho "$1,0,0.0001" # レポートファイルが存在しなかった場合 (ゼロ除算対策)fi}# 各プロジェクトのC0カバレッジ情報を算出し、ファイルに出力for each_project in "${projects[@]}"; doget_coverage "$each_project" >> 'out.csv'done# プロジェクト全体のカバレッジ情報を算出し、ファイルに出力total_covered=$(awk -F ',' '{ it += $2 } END { print it }' 'out.csv')total_instructions=$(awk -F ',' '{ it += $3 } END { print it }' 'out.csv')echo "TOTAL,$total_covered,$total_instructions" >> 'out.csv'
Copyright © 2023 Toranoana Inc. All Rights Reserved.13 実行結果 project1,112,125project2,0,0.0001 # テストが 1 件もないとこのようになるproject3,2,19TOTAL,114,144.0001● 前ページのスクリプトを実行すると、次のファイル (out.csv) を得られる: ● 1列目: プロジェクト名 ● 2列目: テストでカバーされた命令行数 ● 3列目: すべての命令行数 ➔ 「2列目」を「3列目」で割ることで、各プロジェクトおよび プロジェクト全体のC0カバレッジを得ることができる状態になった
Copyright © 2023 Toranoana Inc. All Rights Reserved.14 構成図 集約した カバレッジ情報を Slackアプリに送信
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.#!/bin/bashSLACK_URL="$1" # 引数にSlackのWebhook URLを指定# Slack投稿用の文字列 `results` を生成results=()for each_line in $(cat 'out.csv'); doeach_result=$(echo "$each_line" \| awk -F ',' '{ printf "%-9s: %.2f %% (%d/%d)", $1, $2 / $3 * 100, $2, $3 }')results+=("$each_result")done# Slackに投稿curl "$SLACK_URL" \--header 'Content-Type: application/json' \--data "{\"text\":\"XXXXXプロジェクトのC0カバレッジです:\`\`\`$(printf '%s\n' "${results[@]}")\`\`\`\"}" 例: project1 : 89.60 % (112 / 125 )
Copyright © 2023 Toranoana Inc. All Rights Reserved.16 構成図
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.17 ▼ .github/workflows/submit_coverage_to_slack.yml name: Submit Code Coverage to Slackon:schedule:- cron: '0 0 * * FRI'jobs:build:steps:… 中略 …- name: Collect Coverage with Gradlerun: ./gradlew test- name: Submit coverage to Slackshell: bashenv:SLACK_URL: ${{ secrets.SLACK_URL }}run: ./submit_coverage_to_slack.sh "$SLACK_URL"毎週金曜日の 09:00 に起動 (UTC の 00:00 は JST の 09:00) これまでに紹介したスクリプト(を1つのファイルにしたもの) SlackのWebhook URL
Copyright © 2023 Toranoana Inc. All Rights Reserved.18 構成図 Slackアプリ経由で目的のSlackチャンネルに カバレッジ情報を投稿する ➔Webhook URL
Copyright © 2023 Toranoana Inc. All Rights Reserved.19 SlackのWebhook URLを生成する 1. Slackアプリの管理ページ https://api.slack.com/apps に移動します。 2. Create an AppまたはCreate New Appを押し、From scratchを選択します。 3. App Nameにアプリ名を入力し、 Pick a workspace to develop your app in: にアプリの作成先のワークスペースを選択します。 Create Appを押すとアプリが作成されます。 4. アプリが作成されたら Incoming Webhooks メニューを開き、Activate Incoming Webhooks をOffからOnに変更します。 5. 次にApp Homeメニューを開き、Your App's Presence in Slack のApp Display NameのEditを押し、以下の内容を入力したら Saveを押します。 ○ Display Name (Bot Name) にボットの表示名を入力します。 ○ Default usernameにボットのSlack上のユーザー名を21文字以内の英数字で入力します。 6. もう一度Incoming Webhooks メニューを開き、Webhook URLs for Your Workspace のAdd New Webhookto Workspaceを押します。 7. アプリからSlackワークスペースへの権限リクエスト画面に遷移したら、投稿先のチャンネルを選択して許可するをクリックします。 8. Webhook URLが生成されます。 ※2023年3月末時点の手順です
Copyright © 2023 Toranoana Inc. All Rights Reserved.Copyright © 2023 Toranoana Inc. All Rights Reserved.20 実行結果
Copyright © 2023 Toranoana Inc. All Rights Reserved.21 まとめ 感想 ● JaCoCoでカバレッジを出力できる ● カバレッジ結果を集約するスクリプトをご紹介 ● GitHub Actionsによる定期実行 ● Webhook経由でSlackに投稿 ● カバレッジがSlackなどで定期的に数字として目に 触れるようになることで、テストを書く意識や モチベーションが上がるきっかけにもなると思います。 ● 週の最後の金曜日にこの通知を見ると、 「今週も頑張ってテストを書いたな〜」 という実感や達成感を感じられる気がしています。 今度の技術書典14 (5月21日) で 技術同人誌の新刊を出します♪ 今回の発表内容もより詳しく載っているので、気になった方はぜひお手にとってご覧ください♪ (電子版もあります/どちらも無料 !!) 宣伝!!