如何在单元测试期间检测空的 IEnumerator 函数调用?

How to detect empty IEnumerator function calls during unit testing?

我正在使用 Unity 的播放模式测试单元 运行 枚举器函数(又名协程)。

测试里面会调用更多的子例程,有的是普通函数,有的是IEnumerator函数,这样可以让测试运行,跨越好几帧

[UnityTest]
public IEnumerator Test1( )
{
    SubAction1( );
    yield return SubAction2( );
}

void SubAction1( ) // A sub function that does not need to run over several frames
{ 
}

IEnumerator SubAction2( ) // A sub function that need to span over several frames
{
    ... // More code
    yield return WaitForSeconds( 1 );

    ... // More code
    while( condition == false )
        yield return null; // Wait until condition becomes true to continue

    ... // More code
}

如果我滥用 SubAction2 并像普通函数一样调用它:

SubAction2( ); // without yield return, this is misuse

它仍然会编译并且 运行 静默!这将使 SubAction2 不执行其所有代码。这只是一个小错别字,但这个错误可能会导致整个测试无声无息地失败! SubAction2 是一个 IEnumerator 函数,意味着用 yield return.

调用

我是否有一些方法来进行完整性检查,或者强制使用 'yield return' 调用此函数?

我正在寻找任何可能的解决方案:

我现在的解决方案是用“DoSubAction2”之类的前缀命名所有 IEnumerator 函数,然后进行正则表达式搜索以查找没有“yield return”的“Do”函数调用的出现检查是否有误用。

鉴于您在编写测试时基本上是在尝试引导自己,因此您可以选择一个场景,您总是调用某个 'helper' 方法,如果您错了,让编译器指导您。

一个选项正在使用基类或实用程序来指定调用方法的方式。 然后您可以创建一个带有重载的方法,处理 IEnumerators 或常规方法。

private void Test1()
{
    CallMethod(MethodNoParams);

    CallMethod(() => MethodOneParam(1));

    CallMethod(CoroutineMethod());

    CallMethod(MethodNoParams()); // Does not compile
    CallMethod(CoroutineMethod); // Does not compile
    CallMethod(MethodOneParam(1)); // Does not compile
}

private void MethodNoParams()
{

}

private void MethodOneParam(int something)
{

}

private System.Collections.IEnumerator CoroutineMethod()
{
    yield return new WaitForEndOfFrame();
}



// These methods in utility or base class
public void CallMethod(Action method)
{
    method.Invoke();
}


public void CallMethod(System.Collections.IEnumerator enumerator)
{
    StartCoroutine(enumerator);
}

检查可用选项后,我决定使用 Visual Studio VSIX 扩展并编写 Roslyn 分析器。此类误用将在 IDE 中作为警告提示。

为了完成,我已经上传了所有 analyzer/fixer 代码:Github

这些是我使用的指南:

其他相关内容

  • 根据@derHugo。看起来 Resharper(需要付费订阅)也会对这种模式发出警告。
  • 还有一个开源项目 Roslynator2019,它捆绑了大量代码分析器,专注于通用 C# 中的代码设计,而且它是免费的。但遗憾的是它不包括我的情况。
  • 看起来 C# async-await 也可以用于 Unity 单元测试。它只需要像 UniTask 提供的那样的一些外壳。

谢谢大家的讨论。对于读者,我希望你今天学到了一些新东西。