Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaのテストカバレッジをSlackに投稿してみる.pdf

 JavaのテストカバレッジをSlackに投稿してみる.pdf

「オタクが最新技術を追う LTイベント 2023春」における「JavaのテストカバレッジをSlackに投稿してみる」の登壇資料です。

■イベント情報
https://yumenosora.connpass.com/event/274863/

■今後のイベントについてはこちら
https://yumenosora.connpass.com/

■虎の穴ラボ 採用サイト
https://yumenosora.co.jp/tora-lab/

More Decks by 虎の穴ラボ株式会社

Other Decks in Programming

Transcript

  1. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    Copyright © 2023 Toranoana Inc. All Rights Reserved.
    JavaのテストカバレッジをSlackに
    投稿してみる

    とらのあなラボ 鷺山


    View Slide

  2. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    自己紹介

    業務

    ● とらのあな通販の開発

    ○ バックエンドは Java

    ● サークル様向けシステム (リニューアル)

    ○ バックエンドは Kotlin

    趣味

    ● 旅行とサウナ

    ○ 先月ワーケーション制度を使って鹿児島に
    行ってきました

    ○ サウナ付きホテルに1週間滞在

    ○ 朝サウナ ➔ 仕事 ➔ 夜サウナ


    View Slide

  3. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    アジェンダ

    ● 作ったモノの動作イメージ

    ● 作り方のご紹介

    ○ 構成図

    ○ 使用ライブラリ

    ○ スクリプトのコード

    ● まとめと感想

    3


    View Slide

  4. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    Copyright © 2023 Toranoana Inc. All Rights Reserved.
    作ったモノの動作イメージ

    4

    各サブプロジェクトの
    カバレッジ

    プロジェクト全体のカ
    バレッジ

    ※

    ※C0カバレッジ: テストでカバーされた命令行数 ÷ すべての命令行数

    (命令網羅率)


    View Slide

  5. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    5

    構成図


    View Slide

  6. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    6

    構成図

    …①

    …②

    …③

    …④

    …⑤

    解説する順番


    View Slide

  7. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    7

    構成図

    gradle test や

    mvn test の実行
    ➔ このとき、カバレッジ情報も

      出力されるようにする

    ➔ カバレッジ計測ツールJaCoCoを

      利用


    View Slide

  8. 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/
    より引用


    View Slide

  9. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    9

    構成図

    JaCoCoにより得られた

    カバレッジ情報を

    プロジェクトごとに集約


    View Slide

  10. 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,…

    View Slide

  11. 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カバレッジ=

    「テストでカバーされた命令行数」

     ÷ 「すべての命令行数」


    View Slide

  12. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    Copyright © 2023 Toranoana Inc. All Rights Reserved.
    #!/bin/bash
    projects=('project1' 'project2' 'project3') # プロジェクト名のリスト
    # 入力したプロジェクトのC0カバレッジ情報を返す関数
    get_coverage() {
    local file="build/reports/jacoco/test/jacocoTestReport.csv"
    if [ -f "$1/$file" ]; then
    local 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"
    else
    echo "$1,0,0.0001" # レポートファイルが存在しなかった場合 (ゼロ除算対策)
    fi
    }
    # 各プロジェクトのC0カバレッジ情報を算出し、ファイルに出力
    for each_project in "${projects[@]}"; do
    get_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'


    View Slide

  13. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    13

    実行結果

    project1,112,125
    project2,0,0.0001 # テストが 1 件もないとこのようになる
    project3,2,19
    TOTAL,114,144.0001
    ● 前ページのスクリプトを実行すると、次のファイル (out.csv) を得られる:

    ● 1列目: プロジェクト名

    ● 2列目: テストでカバーされた命令行数

    ● 3列目: すべての命令行数


     ➔ 「2列目」を「3列目」で割ることで、各プロジェクトおよび

    プロジェクト全体のC0カバレッジを得ることができる状態になった


    View Slide

  14. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    14

    構成図

    集約した

    カバレッジ情報を

    Slackアプリに送信


    View Slide

  15. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    Copyright © 2023 Toranoana Inc. All Rights Reserved.
    #!/bin/bash
    SLACK_URL="$1" # 引数にSlackのWebhook URLを指定
    # Slack投稿用の文字列 `results` を生成
    results=()
    for each_line in $(cat 'out.csv'); do
    each_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 ) 


    View Slide

  16. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    16

    構成図


    View Slide

  17. 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 Slack
    on:
    schedule:
    - cron: '0 0 * * FRI'
    jobs:
    build:
    steps:
    … 中略 …
    - name: Collect Coverage with Gradle
    run: ./gradlew test
    - name: Submit coverage to Slack
    shell: bash
    env:
    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


    View Slide

  18. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    18

    構成図

    Slackアプリ経由で目的の
    Slackチャンネルに

    カバレッジ情報を投稿する

    ➔Webhook URL


    View Slide

  19. 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 Webhook
    to Workspaceを押します。

    7. アプリからSlackワークスペースへの権限リクエスト画面に遷移したら、投稿先のチャンネルを選択して
    許可するをクリックします。

    8. Webhook URLが生成されます。 

    ※2023年3月末時点の手順です 


    View Slide

  20. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    Copyright © 2023 Toranoana Inc. All Rights Reserved.
    20

    実行結果


    View Slide

  21. Copyright © 2023 Toranoana Inc. All Rights Reserved.
    21

    まとめ

    感想

    ● JaCoCoでカバレッジを出力できる

    ● カバレッジ結果を集約するスクリプトをご紹介

    ● GitHub Actionsによる定期実行

    ● Webhook経由でSlackに投稿

    ● カバレッジがSlackなどで定期的に数字として目に

    触れるようになることで、テストを書く意識や

    モチベーションが上がるきっかけにもなると思います。


    ● 週の最後の金曜日にこの通知を見ると、

    「今週も頑張ってテストを書いたな〜」

    という実感や達成感を感じられる気がしています。

    今度の技術書典14 (5月21日) で

    技術同人誌の新刊を出します♪ 


    今回の発表内容もより詳しく載っている
    ので、気になった方はぜひお手にとって
    ご覧ください♪

    (電子版もあります/どちらも無料 !!)

    宣伝!!


    View Slide