はじめに
いろんなUnityバージョンに対応したライブラリを作ってて手元でテストするのが面倒だったので、
- GitHub Actionsで
- Unityのバージョンを複数指定して
- すべてのバージョンでUnity Test Framework(旧:Unity Test Runner)によるテストを走らせる
ようなワークフローを書いたので紹介します。
ちなみに冒頭のツイートの画像の内容だとバグっていて、単一のUnityバージョンでしかテストが走らないのでご注意ください。
事前準備
予めUnityのライセンス周りの下準備をしておく必要があります。
自分は以下の記事を参考にしました。
複数のUnityバージョンでテストを走らせる場合でも、条件的にPersonalライセンスが使用可能であれば1つでOKです。
ワークフローを実行する
Unityのライセンス情報をSecretsに登録した状態で↓のファイルを
{リポジトリのルート}/.github/workflows/
以下に置くと、GitHubにpushされたときにテストが実行されます。
name: Run Test
on: [push]
jobs:
test:
name: Test in Unity${{ matrix.unityVersion }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
unityVersion:
- 2021.3.0f1 # 好きなバージョンを指定
- 2022.1.0f1 # 好きなバージョンを指定
steps:
- uses: actions/checkout@v3
with:
lfs: true
path: Unity${{ matrix.unityVersion }}
- uses: actions/cache@v3
with:
path: Unity${{ matrix.unityVersion }}/Library
key: Library-Unity${{ matrix.unityVersion }}
restore-keys: |
Library-
- uses: game-ci/unity-test-runner@5263cf0ab1d1c310c57c1861c71324b7e273909c
id: tests
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
unityVersion: ${{ matrix.unityVersion }}
projectPath: Unity${{ matrix.unityVersion }}
artifactsPath: Unity${{ matrix.unityVersion }}-artifacts
githubToken: ${{ secrets.GITHUB_TOKEN }}
checkName: Unity${{ matrix.unityVersion }} Test Results
- uses: actions/upload-artifact@v3
if: always()
with:
name: Test results for Unity${{ matrix.unityVersion }}
path: ${{ steps.tests.outputs.artifactsPath }}
このワークフローを実行すると
- Unity2021.3.0f1
- Unity2022.1.0f1
の2つのバージョンでそれぞれテストが実行されます。
使うときは # 好きなバージョンを指定
の行を適当に追加/削除/変更してください。
そもそもUnity Test Frameworkがわからない場合は、以下が大変参考になります。
GameCIのサンプルコードはちょっと古い
先に紹介したワークフローは GameCIのドキュメント に記載の以下を参考にしてます。
name: Test project
on: [push, pull_request]
jobs:
testAllModes:
name: Test in ${{ matrix.testMode }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
testMode:
- playmode
- editmode
steps:
- uses: actions/checkout@v2
with:
lfs: true
- uses: actions/cache@v2
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}
restore-keys: |
Library-
- uses: game-ci/unity-test-runner@v2
id: tests
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
projectPath: ${{ matrix.projectPath }}
testMode: ${{ matrix.testMode }}
artifactsPath: ${{ matrix.testMode }}-artifacts
githubToken: ${{ secrets.GITHUB_TOKEN }}
checkName: ${{ matrix.testMode }} Test Results
coverageOptions: 'generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+my.assembly.*'
- uses: actions/upload-artifact@v2
if: always()
with:
name: Test results for ${{ matrix.testMode }}
path: ${{ steps.tests.outputs.artifactsPath }}
- uses: actions/upload-artifact@v2
if: always()
with:
name: Coverage results for ${{ matrix.testMode }}
path: ${{ steps.tests.outputs.coveragePath }}
これを変更して使うにあたってはいくつか注意点があったのでそちらもご紹介します。
Node.js 12に関する警告が出る
そのままだとワークフロー実行時に以下のような警告が出ます。
Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout, actions/cache, game-ci/unity-test-runner, actions/upload-artifact, actions/upload-artifact, actions/cache, actions/checkout
警告に従って、使用されている以下のアクションのバージョンを上げます。 v2
を v3
に書き換えるだけです。
-
actions/checkout@v2
→actions/checkout@v3
-
actions/cache@v2
→actions/cache@v3
-
actions/upload-artifact@v2
→actions/upload-artifact@v3
参考:GitHub ActionsでNode.js 12のサポートが終了します
set-output
に関する警告が出る
まだ以下の警告が出ます。
The
set-output
command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
参考:GitHub Actionsで save-state
とset-output
が廃止されるようです。
これはGameCIの game-ci/unity-test-runner@v2
に起因するものなので、こちらのバージョンを上げます。
game-ci/unity-test-runner
の最新のリリースは現時点で v2.0.3
なのですが、修正が現状 main
ブランチにしか入ってない(#193,#194)ので、最新のコミットのハッシュを直接指定します。
-
game-ci/unity-test-runner@v2
→game-ci/unity-test-runner@5263cf0ab1d1c310c57c1861c71324b7e273909c
もしこの記事を読んだ時点で v2.0.4
がリリースされてたらコミットハッシュの代わりにそちらを指定すると良いと思います。
注意点
複数のUnityバージョンでテストを回すと実行時間が嵩むので、無料枠で動かす場合は注意が必要です。
参考:
- About billing for GitHub Actions(GitHub Docs)
- GitHub Actions の利用状況の確認と無料枠の上限に達した場合の対処方法
- GitHub Actions の無料枠を使いきった場合
おまけ:すべてのプラットフォームでコンパイルが通るかどうかのテスト
複数のUnityバージョンで動作を保証するライブラリ/アセット/フレームワークを作っていて、最低限ほしいのは「サポートするUnityバージョンでビルドが通るかどうかのテスト」です。
ということでC#9.0のUnityで動くテストを書いてみました。 Scriptable Build Pipeline のパッケージが必要です。
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEditor.Build.Player;
public class CompilationTest
{
private static readonly string OutputPath = $"Temp/{nameof(CompilationTest)}";
[Test] public void StandaloneOSX() => Assert.IsTrue(Compile(BuildTarget.StandaloneOSX));
[Test] public void StandaloneWindows() => Assert.IsTrue(Compile(BuildTarget.StandaloneWindows));
[Test] public void iOS() => Assert.IsTrue(Compile(BuildTarget.iOS));
[Test] public void Android() => Assert.IsTrue(Compile(BuildTarget.Android));
[Test] public void StandaloneWindows64() => Assert.IsTrue(Compile(BuildTarget.StandaloneWindows64));
[Test] public void WebGL() => Assert.IsTrue(Compile(BuildTarget.WebGL));
[Test] public void WSAPlayer() => Assert.IsTrue(Compile(BuildTarget.WSAPlayer));
[Test] public void StandaloneLinux64() => Assert.IsTrue(Compile(BuildTarget.StandaloneLinux64));
[Test] public void PS4() => Assert.IsTrue(Compile(BuildTarget.PS4));
[Test] public void XboxOne() => Assert.IsTrue(Compile(BuildTarget.XboxOne));
[Test] public void tvOS() => Assert.IsTrue(Compile(BuildTarget.tvOS));
[Test] public void Switch() => Assert.IsTrue(Compile(BuildTarget.Switch));
[Test] public void Lumin() => Assert.IsTrue(Compile(BuildTarget.Lumin));
[Test] public void Stadia() => Assert.IsTrue(Compile(BuildTarget.Stadia));
[Test] public void CloudRendering() => Assert.IsTrue(Compile(BuildTarget.CloudRendering));
[Test] public void GameCoreXboxSeries() => Assert.IsTrue(Compile(BuildTarget.GameCoreXboxSeries));
[Test] public void GameCoreXboxOne() => Assert.IsTrue(Compile(BuildTarget.GameCoreXboxOne));
[Test] public void PS5() => Assert.IsTrue(Compile(BuildTarget.PS5));
[Test] public void EmbeddedLinux() => Assert.IsTrue(Compile(BuildTarget.EmbeddedLinux));
private static bool Compile(BuildTarget target)
{
var input = new ScriptCompilationSettings
{
target = target,
group = BuildPipeline.GetBuildTargetGroup(target),
};
var result = PlayerBuildInterface.CompilePlayerScripts(input, OutputPath);
var assemblies = result.assemblies;
var passed = (assemblies is { Count: > 0 } && (result.typeDB != null));
if (Directory.Exists(OutputPath)) Directory.Delete(OutputPath, true);
return passed;
}
}
参考:
- 【Unity】各プラットフォームにおいてコンパイルエラーが発生しないか確認できるテストコード
- [Unity] プレイヤービルド時に出るコンパイルエラーを事前にチェックする
- 【Unity】Scriptable Build Pipelineによるビルドフロー構築入門