Open3

テスト用Scriptを楽に作る自分用ライブラリ

naninunenoynaninunenoy

テストスクリプトの作成

テストはまだ書かんけど、とりあえずファイルだけ作っとこみたいなときに使う。
テストファイルにテストするクラスを書いておくとIDEとかで定義に飛べる。

入力ファイル

Hoge.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hoge : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

自動生成されるファイル

HogeTest.cs
using NUnit.Framework;
using System.Collections.Generic;
using System.Collections;
using UnityEngine.TestTools;
using UnityEngine;

namespace Tests
{
    public class HogeTest
    {
        Hoge x = default;
        // A Test behaves as an ordinary method
        [Test]
        public void HogeTestSimplePasses()
        {
            // Use the Assert class to test conditions
        }

        // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
        // `yield return null;` to skip a frame.
        [UnityTest]
        public IEnumerator HogeTestWithEnumeratorPasses()
        {
            // Use the Assert class to test conditions.
            // Use yield to skip a frame.
            yield return null;
        }
    }
}
naninunenoynaninunenoy

テスト用モックの作成

自分のスタイルだと、IObservable みたいなプロパティとか SetXXX(value) UniTask とかのメソッドを interface に定義することがよくある。
で、テストコード用の interface 実装を毎回作るのが大変だったので、自分がよく使うスタイルに対応して自動生成させる。
Setした結果のプロパティとか IObservable に連動した Subject などを公開する。

入力ファイル

IHoge.cs
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UniRx;

namespace HappyTesting {
    public interface IHoge {
        string Hoge { get; }
        void SetHoge(string hoge);
        IObservable<Unit> HogeObsevable { get; }
        IReadOnlyReactiveProperty<int> HogeValue { get; }
        UniTask SetFugaPiyoAsync(string fuga, float piyo,  CancellationToken cancellationToken);
        UniTask<(string, float)> GetFugaPiyoAsync(CancellationToken cancellationToken);
    }
}

自動生成されるファイル

HogeMock.cs
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UniRx;

namespace HappyTesting.Tests
{
    public class HogeTestMock : IHoge
    {
        public string Hoge { set; get; }public string SetHogeHogeResult { private set; get; }
public void SetHoge(string hoge) {
  SetHogeHogeResult = hoge;
}public IObservable<Unit> HogeObsevable => HogeObsevableSubject;
public readonly Subject<Unit> HogeObsevableSubject = new();public IReadOnlyReactiveProperty<int> HogeValue => HogeValueSubject.ToReadOnlyReactiveProperty();
public readonly Subject<int> HogeValueSubject = new();public string SetFugaPiyoAsyncFugaResult { private set; get; }
public float SetFugaPiyoAsyncPiyoResult { private set; get; }
public CancellationToken SetFugaPiyoAsyncCancellationTokenResult { private set; get; }
public async UniTask SetFugaPiyoAsync(string fuga, float piyo, CancellationToken cancellationToken) {
  await UniTask.Yield();
  SetFugaPiyoAsyncFugaResult = fuga;
  SetFugaPiyoAsyncPiyoResult = piyo;
  SetFugaPiyoAsyncCancellationTokenResult = cancellationToken;
}public UniTaskCompletionSource<(string, float)> GetFugaPiyoAsyncCts { get; } = new();
public async UniTask<(string, float)> GetFugaPiyoAsync(CancellationToken cancellationToken) {
  await UniTask.Yield();
  return await GetFugaPiyoAsyncCts.Task;
}
    }
}
成形するとこんな感じ
HogeMock.cs
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UniRx;

namespace HappyTesting.Tests {
    public class HogeTestMock : IHoge {
        public string Hoge { set; get; }
        public string SetHogeHogeResult { private set; get; }

        public void SetHoge(string hoge) {
            SetHogeHogeResult = hoge;
        }

        public IObservable<Unit> HogeObsevable => HogeObsevableSubject;
        public readonly Subject<Unit> HogeObsevableSubject = new();
        public IReadOnlyReactiveProperty<int> HogeValue => HogeValueSubject.ToReadOnlyReactiveProperty();
        public readonly Subject<int> HogeValueSubject = new();
        public string SetFugaPiyoAsyncFugaResult { private set; get; }
        public float SetFugaPiyoAsyncPiyoResult { private set; get; }
        public CancellationToken SetFugaPiyoAsyncCancellationTokenResult { private set; get; }

        public async UniTask SetFugaPiyoAsync(string fuga, float piyo, CancellationToken cancellationToken) {
            await UniTask.Yield();
            SetFugaPiyoAsyncFugaResult = fuga;
            SetFugaPiyoAsyncPiyoResult = piyo;
            SetFugaPiyoAsyncCancellationTokenResult = cancellationToken;
        }

        public UniTaskCompletionSource<(string, float)> GetFugaPiyoAsyncCts { get; } = new();

        public async UniTask<(string, float)> GetFugaPiyoAsync(CancellationToken cancellationToken) {
            await UniTask.Yield();
            return await GetFugaPiyoAsyncCts.Task;
        }
    }
}