勉強不足で至らんブログ

勉強不足ですが、何か発信できればと思っています。

UnityのEditModeTestsをdotnetで実行させる

UnityのTestをUnityEditorを使わないでどうにか走らせれないか?

と考えのがきっかけです。

UnityのCIをCircleCIで頑張る - 勉強不足で至らんブログ

過去CircleCIでUnityEngineが入ったDockerを使っていたりしましたがDockerコンテナのセットアップで

f:id:MakeTake:20200204230713p:plain

長くて3分弱かかります早くて1分程度にはなります。 docker_layer_cachingを使えば10秒くらいのにもできますがUnityEngineの入ったDockerを使おうとすると工夫が必要になります。

工夫なく手軽に使えたらいいのに…と思ったところで

booth.pm

にある

  • 第5章:Unityと.NET Coreでのコード共有

を思い出しました。これでdotnetのtestから走らせればいいのでは…と思ってやってみました。

結果的に今回はEdit Mode Testsであれば可能でした。最後の方に記述しますがPlay Modeももしかするとできるかもしれません。

今回のリポジトリ github.com

CircleCIの結果 https://circleci.com/gh/MizoTake/UnityTestFromDotnet

セットアップ

基本的なセットアップ手順は 第5章:Unityと.NET Coreでのコード共有 にありますのでそちらの手順に添えば大丈夫です。 サンプルリポジトリも公開してるそうです。 github.com

自分は追加でdotnetのプロジェクトの.csprojに

  <ItemGroup>
    <PackageReference Include="NUnit" Version="3.12.0" />
    <PackageReference Include="Unity3D.UnityEngine" Version="2018.3.5.1" />
    <PackageReference Include="coverlet.collector" Version="1.0.1" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.16.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
  </ItemGroup>

を追加しています。基本的にNuGetで検索すればでるはずなので導入方法はやりやすいものがいいと思います。

注意なのは Unity3D.UnityEngine のバージョンが2018台のいくつかしかないことです。バージョンを超える何かを行たい場合は工夫が必要になると思います。

Testを実行する

普通にC#でEdit Mode Testsを記述します。今回はサンプルで

using NUnit.Framework;

public class TestSample
{
    [Test]
    public void Passed()
    {
        Assert.AreEqual(true, true);
    }
    
    [Test]
    public void Failed()
    {
        Assert.AreEqual(true, false);
    }
}

としました。これをUnityのTestRunnerが認識するように作ります。

ただ、少し踏み入ってUnityEngineの参照を行おうとすると参照できないことがあるのでdllの解決をうまくやる必要がありそうです。自分も確認不足でしたのでわかり次第更新します。

あとはdotnet test を実行すればtestが走り、結果が得れます。

手元で得るよりはCIで走らせて見れた方がいいと思うのでCircleCIで走らせました。

version: 2.1

executors:
  dotnet:
    docker:
      - image: mcr.microsoft.com/dotnet/core/sdk:3.0

jobs:
  test:
    executor: dotnet
    steps:
      - checkout
      - run: dotnet tool install trx2junit
      - run: "dotnet test --logger trx || : ; dotnet trx2junit dotnetProject/TestResults/*.trx --output results"
      - store_test_results:
          path: results

workflows:
  version: 2
  test-flow:
    jobs:
      - test

途中でdotnet toolで trx2junit というのを導入していますが dotnet test だとtestの結果は.trxという形式で吐き出されるためです。CircleCIではJUnitCucumberしか対応していないので変換させるためにtrx2junitを使用します。

一度手元でdotnet tool install trx2junitを実行すれば.configというディレクトリに

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "trx2junit": {
      "version": "1.3.0",
      "commands": [
        "trx2junit"
      ]
    }
  }
}

が作成されます。これがあればinstallできるぽいです。もしかすると.configはignoreしていいディレクトリかもしれません。

ともかくこれでCircleCIのTest Summaryに登録でき、エラーがあった場合に f:id:MakeTake:20200204234208p:plain という風に見れるので対処もやりやすくなると思います。

またdotnet test実行時のコマンドは、この形式でないとテストがこけた際にtrxから変換ができずにTest Summaryが使えず終わってしまうのを回避するためのものです。

さいごに

ここまででUnityのEdit Mode Testsをdotnetで実行させる方法の説明は終わりです。UnityEngineがなくても実行できる環境というのは結構魅力的だと思っています。さらにはUnityのactivateが必要ないのでかなり良いです。

いずれPlay Mode Testsも実行させれるようにしてみたいため調べてみると www.nuget.org

があったので試しましたがそのままでは動きませんでした。ただ工夫をすればいけるような感じだったので時間のある時に挑戦してみようかと思います。