如何在 Unity Test Runner 中测试 Unity 协程

Nal*_*ara 5 c# unit-testing coroutine unity-game-engine test-runner

我目前正在使用 Unity 2019 和 C# 开发一款游戏,并为此使用了大量事件和协程。协程是必要的,因为许多计算都是在其中完成的,我不希望游戏在那段时间冻结。现在我开始使用测试运行器(播放模式)编写单元测试,并且协程只是不执行。由于我确实需要确保它们按预期工作,因此不可能仅在“更高级别”进行测试。

我已经尝试过正常的 StartCoroutine() 方法,该方法在测试文件中不起作用(“找不到方法名称”)。此外,我将我的一个协程重构为正常的 void 方法,一切运行良好并且通过了测试。我使用 Visual Studio 调试器来查看它是否跳转到协程执行,但没有。所以问题显然是协程没有执行。我考虑过将计算逻辑移至另一个 void 函数并测试该函数(并省略协程),但我必须确保协程中完成的迭代也能正常工作(它们通常比示例中更复杂)。

这是一个显示一般结构的最小示例(通常需要完成更多计算)。

public class MeasuredValues
{
    List<Vector3> slidingWindow; // this is already filled when Normalize() is executed

    public IEnumerator Normalize()
    {
        //find coordinate system origin
        Vector3 originPosition = GetOrigin(); // returns a Vector3
        //normalization
        for (int i = 0; i < slidingWindow.Count; i++)
        {
            yield return null;
            //reset point to be at (0,y,0)
            slidingWindow[i] -= originPosition;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在测试文件中我想:

[Test]
public void TestNormalization()
{
    MeasuredValues myMeasuredValues = new MeasuredValues();
    // add many Vector3 to slidingWindow
    // call coroutine
    // assert, that the values are now as expected
}
Run Code Online (Sandbox Code Playgroud)

我尝试过myMeasuredValues.Normalize()(不起作用,调试器只是跳过它)并且StartCoroutine(myMeasuredValues.Normalize)(不起作用,StartCoroutine 在该上下文中不可用)。最后,我尝试了

    while (test.Normalize().MoveNext())
    {
        yield return null;
    }
Run Code Online (Sandbox Code Playgroud)

但这永远不会结束,因为MoveNext()永远不会设置为 false。至少调试器跳进了协程方法。

是否有任何易于应用的解决方案可以使用 Visual Studio 或 Unity Test Runner 测试我的协程,而无需重构整个项目结构?

der*_*ugo 3

我尝试过myMeasuredValues.Normalize()(没用,调试器只是跳过了它)

那是当然的,因为这不是你运行协程的方式

并且StartCoroutine(myMeasuredValues.Normalize)(不起作用,StartCoroutine 在该上下文中不可用)。

这是由于StartCoroutine是 的成员MonoBehaviour


更新

实际上使用[UnityTest]而不是[Test]你可以简单地使用

[UnityTest]
public IEnumerator TestNormalization()
{
    MeasuredValues myMeasuredValues = new MeasuredValues();

    // add many Vector3 to slidingWindow
    
    yield return myMeasuredValues.Normalize();

    // assert, that the values are now as expected
}
Run Code Online (Sandbox Code Playgroud)

因为这样测试是由框架作为协程本身执行的。