测试大型状态机的策略是什么?

Pon*_*dum 20 c# unit-testing state-machine mspec

我继承了一个庞大且相当复杂的状态机.它有31种可能的状态,都是真正需要的(大业务流程).它有以下输入:

  • 枚举:当前状态(所以0 - > 30)
  • 枚举:来源(目前只有2个条目)
  • 布尔值:请求
  • 布尔值:类型
  • 枚举:状态(3个州)
  • 枚举:处理(3个州)
  • 布尔值:已完成

将其分解为单独的状态机似乎不可行,因为每个状态都是不同的.我为最常见的输入编写了测试,每个输入有一个测试,所有输入都是常量,除了State.

[Subject("Application Process States")]
public class When_state_is_meeting2Requested : AppProcessBase
{
    Establish context = () =>
    {
        //Setup....
    };

    Because of = () => process.Load(jas, vac);

    It Current_node_should_be_meeting2Requested = () => process.CurrentNode.ShouldBeOfType<meetingRequestedNode>();
    It Can_move_to_clientDeclined = () => Check(process, process.clientDeclined);
    It Can_move_to_meeting1Arranged = () => Check(process, process.meeting1Arranged);
    It Can_move_to_meeting2Arranged = () => Check(process, process.meeting2Arranged);
    It Can_move_to_Reject = () => Check(process, process.Reject);
    It Cannot_move_to_any_other_state = () => AllOthersFalse(process);
}
Run Code Online (Sandbox Code Playgroud)

没有人完全确定每个状态和输入集的输出应该是什么.我已经开始为它编写测试了.但是,我需要写一些像4320测试(30*2*2*2*3*3*2)的东西.

您对测试状态机有什么建议?


编辑:我正在玩所有的建议,并在找到效果最好的时候标记答案.

Fin*_*las 6

我看到了问题,但我肯定会尝试将逻辑分开.

我眼中最大的问题是:

  • 它有31种可能的状态.
  • 它有以下输入:
    • 枚举:当前状态(所以0 - > 30)
    • 枚举:来源(目前只有2个条目)
    • 布尔值:请求
    • 布尔值:类型
    • 枚举:状态(3个州)
    • 枚举:处理(3个州)
    • 布尔值:已完成

有太多的事情发生了.输入使代码难以测试.你已经说过将它分解成更易于管理的区域会很痛苦,但是如果不是更加痛苦的话,那么在开始时测试这么多的逻辑就好了.在您的情况下,每个单元测试覆盖太多的地面.

我问过关于测试大型方法的这个问题本质上是类似的,我发现我的单位太大了.你最终还是会进行很多测试,但它们会更小,更易于管理,覆盖范围更小.这只能是一件好事.

测试旧版代码

看看Pex.您声称继承了此代码,因此实际上这不是测试驱动开发.您只是希望单元测试涵盖每个方面.这是一件好事,因为任何进一步的工作都将得到验证.我个人还没有正确使用Pex,不过我看到的视频让我惊叹不已.本质上,它将基于输入生成单元测试,在这种情况下,输入将是有限状态机本身.它将生成您不会想到的测试用例.虽然这不是TDD,但在这种情况下,测试遗留代码,它应该是理想的.

获得测试覆盖后,您可以开始重构,或者添加具有良好测试覆盖率安全性的新功能,以确保您不会破坏任何现有功能.