GitHub ActionsでJestを実行してテスト結果をWebhookでSlackに通知してみた

GitHub ActionsでJestを実行してテスト結果をWebhookでSlackに通知してみた

Clock Icon2025.04.27

こんにちは!製造ビジネステクノロジー部の小林です。

今回はJavaScriptのテストフレームワークであるJestをGitHub Actionsのワークフロー内で実行し、その結果をSlackに通知する方法をご紹介します。テスト結果をチーム内で共有できるようになれば、開発プロセスの透明性が高まり、問題の早期発見にもつながるかもしれません。

前提条件

  • GitHub アカウント
  • Slack ワークスペースの管理権限(Webhook URL を作成するため)

この記事でお話ししないこと

  • Jestの詳細な使い方
  • TypeScriptの基本文法

プロジェクト構造

githubactions-jest/
├── .github/
│   └── workflows/
│       └── test.yml  # GitHub Actionsの設定ファイル
├── src/
│   ├── calculator.ts  # テスト対象のコード
│   └── calculator.test.ts  # テストコード
├── .gitignore
├── jest.config.js
├── package.json
└── tsconfig.json

Slack Webhook URLの取得

まずはSlackからWebhook URLを取得します。これによりGitHub Actionsから通知を送信できるようになります。取得方法の詳細は下記の記事をご参照ください。
https://dev.classmethod.jp/articles/aws-cdk-security-hub-slack/

GitHub EnvironmentsにSlack Webhook URLを保存

取得したSlack Webhook URLをGitHub Environmentsの変数として保存します。

  1. リポジトリの「Settings」タブを開き、左サイドバーから「Environments」を選択します。
  2. 「New environment」ボタンをクリックして新しい環境を作成します。今回は「dev」という名前にします。
    スクリーンショット 2025-04-26 23.32.54
    スクリーンショット 2025-04-26 23.35.12

「Environment variables」セクションで「Add Environment variables」ボタンを選択します。
スクリーンショット 2025-04-26 23.36.57

Name」フィールドに「SLACK_WEBHOOK_URL」、「Value」フィールドに先ほど取得したSlack Webhook URLを入力後、「Add variable」ボタンで保存します。
スクリーンショット 2025-04-26 23.43.17

以上でEnvironment variablesへの登録は完了です。
スクリーンショット 2025-04-26 23.46.55

ポイント

Environment secretsとEnvironment variablesの違いは、secretsが暗号化されて保存され、ログに表示されないのに対し、variablesは暗号化されないという点です。今回Webhook URLは機密情報として扱わないため、variablesを使用しています。詳細は下記をご参照ください。
https://docs.github.com/ja/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment

TypeScript + Jest プロジェクトの準備

シンプルな計算機能を持つTypeScriptプロジェクトを作成し、Jestでテストできるように設定します。

必要なパッケージのインストール

# プロジェクトの初期化
npm init -y

# TypeScript+Jestのテスト環境をインストール
npm install --save-dev typescript jest ts-jest @types/jest

# TypeScriptの設定ファイル生成
npx tsc --init

tsconfig.jsonの設定

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

jest.config.jsの作成

jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/*.test.ts'],
};

package.jsonにスクリプトを追加

{
  "scripts": {
    "build": "tsc",
    "test": "jest"
  }
}

計算機能の実装
シンプルな四則演算を行う関数を作成します。

calculator.ts
/**
 * 2つの数値を足し算します
 */
export function add(a: number, b: number): number {
  return a + b;
}

/**
 * 2つの数値の引き算を行います
 */
export function subtract(a: number, b: number): number {
  return a - b;
}

/**
 * 2つの数値の掛け算を行います
 */
export function multiply(a: number, b: number): number {
  return a * b;
}

/**
 * 2つの数値の割り算を行います
 */
export function divide(a: number, b: number): number {
  return a / b;
}

テストコードの作成
関数をテストするコードを作成します。最後のテストは後ほどテスト失敗の動作確認で使用するため、一旦コメントアウトしておきます。

calculator.test.ts
import { add, subtract, multiply, divide } from './calculator';

describe('Calculator', () => {
  test('2つの数値を足し算できる', () => {
    expect(add(1, 2)).toBe(3);
    expect(add(5, -3)).toBe(2);
  });

  test('2つの数値を引き算できる', () => {
    expect(subtract(5, 2)).toBe(3);
    expect(subtract(5, -3)).toBe(8);
  });

  test('2つの数値を掛け算できる', () => {
    expect(multiply(3, 4)).toBe(12);
    expect(multiply(3, -4)).toBe(-12);
  });

  test('2つの数値を割り算できる', () => {
    expect(divide(10, 2)).toBe(5);
    expect(divide(10, -2)).toBe(-5);
  });

  // わざと失敗するテスト
  // test('このテストは失敗します', () => {
  //   expect(add(1, 1)).toBe(3); // 1 + 1 = 2 なので、3を期待すると失敗する
  // });
});

GitHub Actionsのワークフロー作成

GitHub Actionsのワークフローファイルを作成します。このファイルは.github/workflows/test.ymlに保存します。下記の公式リポジトリを参考に作成しました。
https://github.com/slackapi/slack-github-action?tab=readme-ov-file

test
# テストを実行してSlackに通知するワークフロー
name: Jest Tests and Notify Slack

on:
  workflow_dispatch:  # 手動でワークフローを実行するためのトリガー

jobs:
  test:
    runs-on: ubuntu-latest  # Ubuntu最新版で実行
    environment: dev  # 環境変数やシークレットを取得する環境を指定

    steps:
    - name: Checkout code  # リポジトリのコードをチェックアウト
      uses: actions/checkout@v4

    - name: Set up Node.js  # Node.jsのセットアップ
      uses: actions/setup-node@v4
      with:
        node-version: '20'  # Node.js v20を使用
        cache: 'npm'  # npmのキャッシュを有効化して高速化

    - name: Install dependencies  # 依存関係のインストール
      run: npm ci  # クリーンインストール(package-lock.jsonを厳密に使用)

    - name: Build TypeScript  # TypeScriptのビルド
      run: npm run build

    - name: Run tests  # テストの実行
      run: npm test

    - name: Notify Slack  # テスト結果をSlackに通知
      if: always()  # テストが成功しても失敗しても常に実行
      uses: slackapi/slack-github-action@v2.0.0  # Slack通知用のアクション
      with:
        webhook: ${{ vars.SLACK_WEBHOOK_URL }}  # SlackのWebhook URL(環境変数から取得)
        webhook-type: incoming-webhook  # Webhookタイプ
        payload: |  # Slackに送信するペイロード
          text: "Test ${{ job.status == 'success' && 'Success' || 'Failed' }}"  # フォールバックテキスト
          blocks:  # Slackのブロックキット形式でメッセージを構成
            - type: "section"  # セクションブロック:テスト結果のステータス表示
              text:
                type: "mrkdwn"
                text: "${{ job.status == 'success' && ':white_check_mark:' || ':x:' }} Test Result:${{ job.status == 'success' && 'Success' || 'Failure' }}"
            - type: "divider"  # 区切り線
            - type: "section"  # リポジトリ情報表示
              fields:
                - type: "mrkdwn"
                  text: "*リポジトリ:*\n${{ github.repository }}"
            - type: "section"  # ブランチ情報表示
              fields:
                - type: "mrkdwn"
                  text: "*ブランチ:*\n${{ github.ref_name }}"
            - type: "section"  # 実行者情報表示
              fields:
                - type: "mrkdwn"
                  text: "*実行者:*\n${{ github.actor }}"
            - type: "actions"  # アクションブロック:ボタンを表示
              elements:
                - type: "button"  # ワークフロー詳細へのリンクボタン
                  text:
                    type: "plain_text"
                    text: "ワークフロー詳細"
                  url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

このワークフローは、手動で実行したときにJestテストを実行し、その結果をSlackに通知します。テスト結果、リポジトリ情報、ブランチ名、実行者などの情報が含まれたメッセージがSlackに送信されます。

動作確認

設定したワークフローを実行して、実際にSlackに通知が届くか確認してみましょう!

  1. GitHub Actionsのタブを開き、「Jest Tests and Notify Slack」ワークフローを選択します。
  2. 「Run workflow」ボタンをクリックして、ワークフローを手動で実行します。
    スクリーンショット 2025-04-27 15.14.05

ワークフローが完了すると、設定したSlackチャンネルに通知が届きます。
「テスト」チャンネルに無事通知が届いていることが確認できました。
スクリーンショット 2025-04-27 15.16.45

「ワークフロー詳細ボタン」を選択すると実行したワークフロー画面に遷移します。
スクリーンショット 2025-04-27 15.21.40

テスト失敗時の通知確認
次に、意図的にテストを失敗させて、失敗時の通知も確認してみましょう。
calculator.test.tsファイルを開き、コメントアウトしていた「わざと失敗するテスト」のコメントを外します。

calculator.test.ts
  // わざと失敗するテスト
  test('このテストは失敗します', () => {
    expect(add(1, 1)).toBe(3); // 1 + 1 = 2 なので、3を期待すると失敗する
  });

変更をコミットしてプッシュし、再度ワークフローを手動で実行します。
テストが失敗すると、Slackに失敗通知が届きます。
スクリーンショット 2025-04-27 15.25.40

ワークフロー詳細画面でも失敗が確認できます。
スクリーンショット 2025-04-27 15.26.26

よりリッチなSlack通知の実装にしたいぜ...!

標準のSlack通知も十分機能的ですが、視覚的にもっと分かりやすくしたいと思います。Slackの公式ドキュメントを見ると、色付きのアタッチメントやカスタムアイコンなどを使って通知をカスタマイズできることがわかります。

GitHub Actionsのエコシステムには様々なSlack通知用のアクションがあります。今回はrtCamp/action-slack-notifyを使って、より見やすい通知を実装してみましょう!
https://github.com/rtCamp/action-slack-notify#environment-variables
スクリーンショット 2025-04-27 15.31.07

実装してみた

test.yml
# Jest テストを実行し、結果をSlackに通知するワークフロー
name: Jest Tests and Notify Slack

on:
  workflow_dispatch:  # 手動でワークフローを実行するためのトリガー

jobs:
  test:
    runs-on: ubuntu-latest  # Ubuntu最新版の仮想環境で実行
    environment: dev  # 環境変数やシークレットを取得する環境を指定

    steps:
    - name: Checkout code  # リポジトリのコードをチェックアウト
      uses: actions/checkout@v4

    - name: Set up Node.js  # Node.js環境のセットアップ
      uses: actions/setup-node@v4
      with:
        node-version: '20'  # Node.js v20を使用
        cache: 'npm'  # npmのキャッシュを有効化してビルド高速化

    - name: Install dependencies  # 依存パッケージのインストール
      run: npm ci  # クリーンインストール(package-lock.jsonを厳密に使用)

    - name: Build TypeScript  # TypeScriptのビルドプロセス実行
      run: npm run build

    - name: Run tests  # Jestテストの実行
      run: npm test

    - name: Slack Notification  # テスト結果をSlackに通知
      uses: rtCamp/action-slack-notify@v2.2.0  # Slack通知用のアクション
      if: always()  # テストの成功/失敗に関わらず常に通知を送信
      env:
        SLACK_WEBHOOK: ${{ vars.SLACK_WEBHOOK_URL }}  # SlackのWebhook URL(環境変数から取得)
        SLACK_COLOR: ${{ job.status == 'success' && 'good' || 'danger' }}  # 成功時は緑、失敗時は赤
        SLACK_ICON: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png  # 通知アイコン
        SLACK_USERNAME: GitHub Actions Notifier  # 通知の送信者名
        SLACK_TITLE: "${{ job.status == 'success' && ':white_check_mark:' || ':x:' }} テスト結果:${{ job.status == 'success' && '成功' || '失敗' }}"  # 通知タイトル
        SLACK_MESSAGE: |  # 通知本文(複数行)
          *リポジトリ:* ${{ github.repository }}  # リポジトリ名を表示
          *ブランチ:* ${{ github.ref_name }}  # ブランチ名を表示
          *実行者:* ${{ github.actor }}  # ワークフロー実行者を表示

          <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|ワークフロー詳細>  # ワークフロー実行へのリンク
        SLACK_FOOTER: ""  # フッターは空に設定
        MSG_MINIMAL: "true"  # リファレンスとイベント情報を非表示に設定

主な変更点は以下の通りです。

  • slackapi/slack-github-actionからrtCamp/action-slack-notifyに変更
  • 環境変数を使って通知の見た目をカスタマイズ
    -- SLACK_COLOR: テスト結果に応じて緑(成功)または赤(失敗)を設定
    -- SLACK_ICON: GitHubのロゴを通知アイコンとして使用
    -- SLACK_USERNAME: 通知の送信者名を設定
    -- SLACK_TITLE: テスト結果のタイトル(絵文字付き)
    -- SLACK_MESSAGE: 通知の本文(リポジトリ、ブランチ、実行者情報など)
    -- MSG_MINIMAL: 余分な情報を非表示にする設定

ワークフローを再度実行すると、以下のようなリッチな通知がSlackに届きます。
スクリーンショット 2025-04-27 15.54.12

以前の通知と比べて、色付きのサイドバーが追加され、視覚的にテスト結果が一目で分かるようになりました。また、GitHubのアイコンが表示され、通知の送信元が明確になっています。

おわりに

GitHub ActionsとSlackを連携させることで、テスト結果を自動的にチームへ通知する仕組みを構築しました。この連携により、テスト失敗をすぐに検知でき、問題の早期発見と迅速な解決が可能になります。

今回はJestテストを例に実装しましたが、この仕組みは他のテストフレームワークやCI/CDパイプラインにも簡単に応用できます。PlaywrightやSeleniumを使ったE2Eテストにも同様の通知を設定できるでしょう。

さらに、GitHub Actionsのスケジュール機能を活用すれば、夜間や週末など定期的にテストを実行し、結果を自動通知することも可能です。これによって継続的にコードの品質を監視し、安定したプロダクト開発を実現できます。

この記事で紹介した方法が、皆様の開発プロセスの効率化と品質向上のお役に立てば幸いです!

参考リンク

https://tools.slack.dev/slack-github-action/
https://dev.classmethod.jp/articles/github-actions-configuration-variables-vs-environment-variables/
https://dev.classmethod.jp/articles/github-actions-environment-secrets-and-environment-variables/

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.