はじめに
この記事はNTTコノキュー アドベントカレンダー2025の記事です。
こんにちは、NTTコノキューの中矢です。業務ではUnityとC#、最近はKotlinと格闘しています。
本記事は、Kotlin(Android)のユニットテストをGitHub Actionsで回す方法の紹介記事です。最近はAndroid XRでKotlinを利用するため、XR業界でもKotlinの単体テストを自動化したい需要が出てくるのかなと思っています。
この記事が少しでも、Androidのユニットテストに挑戦する人の参考になれば幸いです。
環境
本記事では後述のself-hosted runnerで動かすため、以下の環境で動作させています。
MacBook Apple M4
Android Studio Narwhal 4 Feature Drop | 2025.1.4 Canary 2
本記事のゴール
GitHub のプルリクエストに連携して、ユニットテストをActionsで回すようにします。 そしてテストレポートも出力できるようにします。


また、保険でdevelopブランチのユニットテストを手動で回せるようにします。

GitHub ActionsのRunnerについて
GitHub Actionsを動作させるには以下の2種類の方法があります。
ここで、GitHub-hosted runnerはGitHubのサーバを使って動作させるため、使えば使うほどお金がかかります。面倒ですね。
しかし、Self-hosted runnerは自身が所持するローカルPC上でActionsを動作させることで、タダで動かすことができます。メンテの必要性がありますが、コストがかからないのは大きな魅力です。
さらに、GitHub-hosted runnerは何も無い環境から動作させるため、いろんなものをインストールしてから動かすため、実行時間がそこそこかかります。
しかし、Self-hosted runnerは既存の環境を利用するため、環境構築の手間はかかりますが、実行時間がGitHub-hosted runnerより少なく済みます。
よって本記事ではSelf-hosted runnerを利用してActionsを動かすことにしました。(実務でもSelf-hosted runnerを使うことが多いです)
準備
Self-hosted runnerを使う方法について説明します。
まず利用しているリポジトリのSettings > Actions > Runnersを選択し、New self-hosted runnerをクリックします。

すると、以下のようにRunner imageを環境に応じて選び、書いてある通りにダウンロードとセットアップすると、そのPCでActionsが動くようになります。

ちなみに、環境でmacOSを選ぶとArchitectureがデフォルトでx64になるので注意です。最近のmacOSはARM64の方が主流だと思うため、しっかりARM64にしましょう。私は2-3回これに引っかかって、アーキテクチャーが異なるから動かねえ!というエラーを喰らっています。学習してほしいですね。
もろもろセットアップして以下コマンドを打つと待機状態になります。
./run.sh
GitHub ActionsのYAML
続いて、プルリク時にユニットテストを回す本体のYAMLを解説します。
まず、お好きなGitリポジトリに、.github/workflowsのディレクトリを作成し、その配下にYAMLファイルを配置します。ここではandroidxr-unit-test.ymlとします。

この状態でGitリポジトリにPushすると、Actionsが動くようになります。
次にYAMLファイルの中身を見ていきます。全文は以下です。 プルリク〜テストレポート作成、保険の手動実行が書かれています。
name: AndroidXR Unit Test
on:
workflow_dispatch:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
jobs:
test:
name: Run tests on Self-Hosted Runner
# self-hosted ランナーを指定
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Run unit tests
run: ./gradlew testDebugUnitTest
# テストレポートをHTML形式で生成(ただし容量節約のため、上書き保存)
- name: Upload test reports
if: always()
uses: actions/upload-artifact@v4
with:
name: unit-test-reports
path: app/build/reports/tests/testDebugUnitTest/
# PRのコメントにレポートのダウンロードリンクが記載のページへのリンクを追加
- name: Comment artifact link on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request?.number;
if (pr) {
const runId = process.env.GITHUB_RUN_ID;
const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
github.rest.issues.createComment({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo,
body: `📝 [テストレポートはこちらからダウンロードおよびindex.htmlから閲覧可能です](${artifactUrl})`
});
}
ひとつひとつ見ていきます。
name: AndroidXR Unit Test
nameは本Actionsの名前で、これがGitHub上に表記されます。

on:
workflow_dispatch:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
onは起動する条件で、workflow_dispatchが手動実行できることを意味します。
そしてdevelopブランチへのマージと、developブランチへマージするプルリクエスト時に自動起動するようにしています。
続いてActionsの実行内容、Jobを設定していきます。まず以下のようにself-hosted runnnerを指定します。
jobs:
test:
name: Run tests on Self-Hosted Runner
# self-hosted ランナーを指定
runs-on: self-hosted
Job本体の一番最初はリポジトリからのコードのチェックアウトです。
steps:
- name: Checkout repository
uses: actions/checkout@v4
次にJDKのセットアップしています。
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
そして、実行権限を渡して、Android StudioでtestDebugUnitTest(ユニットテスト)を回しています。
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Run unit tests
run: ./gradlew testDebugUnitTest
これでユニットテスト自体はプルリク時に自動で回るようになります。
最後の以下のスクリプトはテストレポートを出力するものです。本スクリプトは不要であれば使わなくてもいいかなと思います。個人的にはテスト失敗したときに何が起きたかわかりやすいので、見やすくするのは好みです。
# テストレポートをHTML形式で生成(ただし容量節約のため、上書き保存)
- name: Upload test reports
if: always()
uses: actions/upload-artifact@v4
with:
name: unit-test-reports
path: app/build/reports/tests/testDebugUnitTest/
# PRのコメントにレポートのダウンロードリンクが記載のページへのリンクを追加
- name: Comment artifact link on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request?.number;
if (pr) {
const runId = process.env.GITHUB_RUN_ID;
const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
github.rest.issues.createComment({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo,
body: `📝 [テストレポートはこちらからダウンロードおよびindex.htmlから閲覧可能です](${artifactUrl})`
});
}
これを実装することで、以下がGitHubのプルリク上に出てきます。

テストレポートは以下みたいな感じです。ローカルで動かしているので、クラウドにアップロードしているわけでもなくかつ、お金がかからないのもいいですね。

まとめ
本記事ではGitHub ActionsでのKotlin(Android)のユニットテストの自動化について紹介しました。Android XRにおいても、今までのKotlin(Android)のユニットテストのノウハウがそのまま活きるため、Androidエンジニアがとても参入しやすくなっているなと思います。
また、GitHubのプルリク機能と連携することで、ユニットテストを回す手間を少しでも削減し、ユニットテストを回すハードルを下げつつ、品質を高めることができるので、可能な限りユニットテストは自動化したいですね。