C# 自動テストの構築方法 Github Actions x xUnit
はじめに
C# で単体テストを導入したあと、「Push したタイミングで自動でテストが走ってくれたら便利だな」と思ったことはありませんか?
本記事では、GitHub Actions を使って、xUnit による C# プロジェクトのテストを自動化する方法を、実際のファイル構成や yml 記述例とともに解説します。
- GitHub 上で CI(継続的インテグレーション)を試してみたい
 - xUnit のテスト実行を自動化したい
 - テスト結果をブラウザで確認できるようにしたい
 - ワークフローファイル 
ymlの具体的な書き方を知りたい 
といった方に向けた内容になっています。
筆者自身、C# × GitHub Actions の組み合わせに初めて触れたときは、仮想マシン特有のエラー、レポート出力の設定などにかなり手こずりました。
環境が変わればすぐにエラーが発生するかと思います。
ですので、本記事ではコードの提示だけでなく、個別の解説も丁寧にしてみました。
CI 初心者の方でも安心して導入できる...はず。
解説に使用したコードはこちらで公開しています。
xUnit の導入がまだという方は、以下の記事からご覧ください。
前提
- Visual Studio 2022 を使用し、C# でアプリケーションを開発している
 - xUnit による単体テストの構築が完了している
 - ソースコードは GitHub 上で管理している
 - Windows 向けアプリの開発であり、Windows 環境での CI 実行を想定している
 
ubuntu-latest など Linux 仮想マシンでも同様の構成は可能ですが、パス記述、依存関係、レポート設定など、環境に合わせた調整が必要になります。
記事内で使用するサンプルソリューションの構成は以下の通りです:
your_repository/
├── .git/
└── MyConsoleApp/
MyConsoleApp/
├── MyConsoleApp/
│   ├── Calculator.cs    // テスト対象のクラス
│   └── Program.cs
└── MyTest/    // xUnit 単体テスト用プロジェクト
     └── CalculatorTest.cs

参考サイト
ワークフロー ファイル(yml) の作成
GitHub Actions を使ってテストを自動化するには、.github/workflows/ フォルダにワークフローファイル(test.yml)を作成する必要があります。
以下のようなディレクトリ構成になるように準備しましょう。
your_repository/
├── .git/
├── .github/
│   └── workflows/
│       └── test.yml
└── MyConsoleApp/
解説の進め方
test.yml に記述する内容は少し長くなります。
「セクションごとに個別の解説」→「最後に全体の完成コードを提示」という流れで説明していきます。
1. name: ワークフロー名の定義
GitHub Actions 上で表示されるワークフローの名前を指定します。
name: .NET Test
2. on: トリガーの定義
どのタイミングで GitHub Actions を起動させるかを指定します。
多数の設定が用意されているので、使い道が多そうなモノをピックアップして紹介します。
- 
mainブランチ、及び、develop/以下のブランチに対するpush - 
mainブランチに対するpull_request 
on:
  push:
    branches:
      - main
      - 'develop/**'
  pull_request:
    branches:
      - main
- C# のコード 
.csが含まれるpush 
on:
  push:
    branches:
      - main
    paths:
      - '**.cs'
- 
docsディレクトリ外のファイルが含まれるpush 
on:
  push:
    branches:
      - main
    paths-ignore:
      - 'docs/**'
3. jobs: 実行する処理の定義
実際に行う処理(ビルドやテストなど)を記述するセクションです。
内容が最も長くなる箇所でもあります。
4. build: 実行環境(OS)の定義
どのOSでジョブを動かすかを指定します。
特に理由がなければ ubuntu-latest がおすすめです。
今回は Windows 用のアプリなので、windows-latest を指定します。
jobs:
  build:
    runs-on: windows-latest
2025年3月現在、指定可能な環境:
| OS | タグ名 | 
|---|---|
| Linux | 
ubuntu-latest、ubuntu-24.04、ubuntu-22.04、ubuntu-20.04
 | 
| Windows | 
windows-latest、windows-2025(プレビュー)、windows-2022 他 | 
| macOS | 
macos-13、macos-14、macos-15(Apple Silicon) | 
5. steps: 実行ステップの定義
各 step に処理を記述します。
- name: が処理の区切り・説明となります。
steps:
  - name: 処理の説明(任意)
    uses: または run: を指定
5-1. コードのチェックアウト
GitHub のリポジトリ内容を仮想マシンに取り込みます。ほぼ全てのワークフローで必要です。
- name: Checkout repository
  uses: actions/checkout@v3
5-2. .NET SDK のセットアップ
開発に使っているバージョンに合わせて dotnet-version を指定します。
- name: Setup .NET 5.x
  uses: actions/setup-dotnet@v4
  with:
    dotnet-version: '5.x'
5-3. 依存関係のインストール
*.csproj に記載された NuGet パッケージを復元します。
working-directory: にて ソリューションファイル .sln があるディレクトリを指定しています。
- name: Restore dependencies
  run: dotnet restore
  working-directory: ./MyConsoleApp
5-4. ビルド
事前に dotnet restore で依存関係を解決しているため、ここでは --no-restore を付けてビルドのみを実行します。
- name: Build
  run: dotnet build --no-restore
  working-directory: ./MyConsoleApp
5-5. テストの実行
xUnit で単体テストを行い、結果を XML で出力させます。
ここで出力される test_result.xml は、次のステップで GitHub Actions 上に表示するための元データになります。
working-directory: にて テスト用のプロジェクトファイル .csproj があるディレクトリを指定しています。
- name: Run xUnit tests
  run: dotnet test --no-build --logger:"xunit;LogFilePath=test_result.xml"
  working-directory: ./MyConsoleApp/MyTest
5-6. テスト結果の出力
前のステップで出力した test_result.xml をもとに、GitHub Actions 上にテスト結果を可視化します。
GitHub Actions の「チェック」画面上にテストの成功・失敗状況を表示できるようにします。
if: always() をつけることで、テストが失敗してもレポート出力がスキップされないようにします。
- name: Publish test results as GitHub report
  uses: EnricoMi/publish-unit-test-result-action/windows@v2
  if: always()
  with:
      files: ./MyConsoleApp/MyTest/test_result.xml
test.yml 全体の完成形
name: .NET Test
on:
  push:
    branches:
      - main
      - 'develop/**'
    paths:
      - '**.cs'
      - '**.yml'
  pull_request:
    branches:
      - main
jobs:
  build:
    runs-on: windows-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
      - name: Setup .NET 5.x
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '5.x'
      - name: Restore dependencies
        run: dotnet restore
        working-directory: ./MyConsoleApp
      - name: Build
        run: dotnet build --no-restore
        working-directory: ./MyConsoleApp
      - name: Run xUnit tests
        run: dotnet test --no-build --logger:"xunit;LogFilePath=test_result.xml"
        working-directory: ./MyConsoleApp/MyTest
      
      - name: Publish test results as GitHub report
        uses: EnricoMi/publish-unit-test-result-action/windows@v2
        if: always()
        with:
          files: ./MyConsoleApp/MyTest/test_result.xml
自動テストを行う前に
1. テスト結果のレポートについて
GitHub Actions のブラウザ上でテスト結果を可視化するため、先ほどの yml 設定ではレポート出力のステップを追加しました。
今回は Windows 仮想マシンですので、マルチプラットフォーム(Windows / Linux / macOS)かつ複数言語をサポートしていた publish-unit-test-result-action を選びました。
他のレポート方法
以下の記事では、他のテストレポート出力手段についても紹介されています。
注意点:
- 一部のツールは Ubuntu 専用 など、仮想マシンの種類に依存することがあります
 - 使用する言語(C#, Python, JavaScriptなど)やテストフレームワークに応じて、ロガーの指定や出力形式が異なります
 
2. ロガーの準備
publish-unit-test-result-action を使って xUnit のテスト結果を GitHub Actions に表示するには、XunitXml.TestLogger というロガーが必要です。
このロガーは、xUnit プロジェクトのテンプレートには含まれていないため、手動で追加インストールする必要があります。
インストール方法(Visual Studio 2022)
Visual Studio 2022 にてターミナルを開きます。

テスト用のプロジェクトに移動し、インストールコマンドを実行します。
your_repository\MyConsoleApp> cd MyTest
your_repository\MyConsoleApp\MyTest> dotnet add package XunitXml.TestLogger --version 6.1.0
3. 権限設定
なぜ権限設定が必要か
GitHub Actions でテスト結果をブラウザ上に表示するには、GitHub が自動で発行するトークン(GITHUB_TOKEN)に「書き込み権限」が必要です。
この設定をしておかないと、テスト結果を表示しようとしても「403 Forbidden」エラーで失敗してしまいます。
そのため、あらかじめリポジトリの設定から 権限を Read and write に変更しておく必要があります。
設定方法
GitHub のリポジトリページを開いたら、上部の Settings タブをクリックします。
Actions > General をクリックします。

下にスクロールし、Workflow permissions を探します。
Read and write permissions を選択し、Save を押します。

4. ビルドエラー対策
仮想マシンと日本語の相性が悪いです。
.cs のコード中に Console.WriteLine("日本語のログ"); があるとビルドエラーが起こります。
- ログ出力には英語を使う
Console.WriteLine("This is Log");
 - 日本語の説明が必要な場合はコメントに記述する
- 
// これは日本語の説明ですは大丈夫です 
 - 
 
具体的にどんなエラーが起きるのか?
Build 工程(Run dotnet build --no-restore)でエラーが発生します。
MyTest\CalculatorTest.cs(26,39): error CS1009: Unrecognized escape sequence
仮想マシンでコードがどのように認識されているかを確認してみます。
- name: Show CalculatorTest.cs contents
  run: type MyTest\CalculatorTest.cs
  working-directory: ./MyConsoleApp
エラーが出ていた行を抜き出します。
[Fact]
public void AddTestLog()
{
    Assert.Equal(3, _calculator.Add(1, 2));
    _output.WriteLine("���O��\���ł��܂�");
    Console.WriteLine("�������͕\������Ȃ�");
}
Console.WriteLine に記載した日本語が文字化けしています。
ログを表示できます- -> 
���O��\���ł��܂� 
ここに含まれている \ が Unrecognized escape sequence の原因だと思われます。
自動テストの実行
yml ファイルや各種コードを main ブランチに push してくだい。
テスト結果の確認
Actions から確認
GitHub のリポジトリページを開いたら、上部の Actions タブをクリックします。

ページには、直近で実行されたワークフロー(test.yml の処理)一覧が表示されます。
- 正常終了:✅ 緑のチェックマーク
 - エラーあり:❌ 赤いバツ印
 
今回は、コミットメッセージが XunitXml.TestLoggerをインストール のものをクリックしてみます。

次の画面では、test.yml の jobs: セクションで定義した build: が表示されます。
ここをクリックすると、その中で実行された各 steps: の詳細が確認できます。

publish-unit-test-result-action を使用している場合、左側メニューに Test Results という項目が表示されます。
これをクリックすると、GitHub Actions 上でテスト結果を可視化することができます。

テストの実行結果が確認できます。
今回はシンプルな XML ロガーによるレポートを使用していますが、よりリッチな形式(HTML や PR コメントなど)での表示も可能です。

コミット欄から確認
テスト結果は Actions タブだけでなく、コミット一覧の画面からも確認できます。
- 
- GitHub のリポジトリ画面で、Code タブを開きます
 
 - 
- 画面上部にある最新のコミット一覧から、確認したいコミットを見つけます
 
 - 
- コミットメッセージの下にある 
☑ 2/2(チェックマークと数値)をクリックします 
- ☑ = ワークフローの成否
 - 2/2 は「2つのジョブ中、2つ成功」を意味しています
 
 - コミットメッセージの下にある 
 - 
- 次の画面で、実行されたワークフロー(例:.NET Test build / Test Results (push))が一覧表示されます
 
 - 
- 
Detailsをクリックすると、GitHub Actions の詳細画面に遷移します 
 - 
 - 
- テスト結果や各ステップのログを確認できます
 
 

Github Actions 使用料について
プライベート リポジトリの場合、使用制限があります。
GitHub Free アカウントの場合、月当たり 2,000 分 を無料で利用可能です。
なお、パブリック リポジトリは無料です。
| プラン | 分 (月あたり) | 
|---|---|
| GitHub Free | 2,000 分 | 
| GitHub Pro | 3,000 分 | 
| 組織の GitHub Free | 2,000 分 | 
| GitHub Team | 3,000 分 | 
| GitHub Enterprise Cloud | 50,000 分 | 
OS によって実際の稼働時間に倍率がかかります。
| オペレーティングシステム | 分の倍率 | 
|---|---|
| Linux | 1 | 
| Windows | 2 | 
| macOS | 10 | 
無料枠が十分に大きいので、個人開発なら気にする必要はない気がしますが...。
頭の片隅で、ubuntu の方がコスパが良いと覚えておくと良いかもしれません。
無料枠を超過した場合
無料枠がリセット(月ごと)されるまで、GitHub Actions が実行されなくなります。
月ごとの請求のお客様の場合、アカウントには既定の使用制限として 0 米ドル (USD) が設定されます。これにより、プライベート リポジトリで、そのアカウントに含まれる容量を超える追加の時間 (分) やストレージが使われるのを防ぐことができます。 アカウントを請求書で支払っている場合、そのアカウントの既定の使用制限は無制限となります。
自身の利用状況を確認する方法
Setting を開きます。
Billing & Licensing > Overview をクリックします。
こちらの画面で使用料金が確認できます。


Current included usage の More Details をクリックすると、残りの無料枠を確認できます。

おわりに
本記事では、C# プロジェクトに GitHub Actions を導入し、xUnit テストを自動実行・レポート出力する方法を解説しました。
CI による自動テストが導入できると、
- プルリクエスト時に自動でテストが走り、安心してレビューできる
 - 小さなバグにもすぐ気づける
 - チームでの開発でも品質を保ちやすくなる
 
など、開発体験がぐっと良くなります。
今回ご紹介した構成は、必要最小限なものです。
- テスト結果の HTML レポート化
 - カバレッジの可視化や PR コメントへの出力
 - 複数のターゲットフレームワークに対する並列テスト実行
 
などを組み合わせることで、より柔軟でパワフルな CI 構成へと拡張していくこともできます。
「まずは試してみたい」という方にとって、本記事がその第一歩になれば幸いです。
Discussion