Pon*_*dum 20 c# unit-testing state-machine mspec
我继承了一个庞大且相当复杂的状态机.它有31种可能的状态,都是真正需要的(大业务流程).它有以下输入:
将其分解为单独的状态机似乎不可行,因为每个状态都是不同的.我为最常见的输入编写了测试,每个输入有一个测试,所有输入都是常量,除了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)的东西.
您对测试状态机有什么建议?
编辑:我正在玩所有的建议,并在找到效果最好的时候标记答案.
我看到了问题,但我肯定会尝试将逻辑分开.
我眼中最大的问题是:
- 它有31种可能的状态.
- 它有以下输入:
- 枚举:当前状态(所以0 - > 30)
- 枚举:来源(目前只有2个条目)
- 布尔值:请求
- 布尔值:类型
- 枚举:状态(3个州)
- 枚举:处理(3个州)
- 布尔值:已完成
有太多的事情发生了.输入使代码难以测试.你已经说过将它分解成更易于管理的区域会很痛苦,但是如果不是更加痛苦的话,那么在开始时测试这么多的逻辑就好了.在您的情况下,每个单元测试覆盖太多的地面.
我问过关于测试大型方法的这个问题本质上是类似的,我发现我的单位太大了.你最终还是会进行很多测试,但它们会更小,更易于管理,覆盖范围更小.这只能是一件好事.
测试旧版代码
看看Pex.您声称继承了此代码,因此实际上这不是测试驱动开发.您只是希望单元测试涵盖每个方面.这是一件好事,因为任何进一步的工作都将得到验证.我个人还没有正确使用Pex,不过我看到的视频让我惊叹不已.本质上,它将基于输入生成单元测试,在这种情况下,输入将是有限状态机本身.它将生成您不会想到的测试用例.虽然这不是TDD,但在这种情况下,测试遗留代码,它应该是理想的.
获得测试覆盖后,您可以开始重构,或者添加具有良好测试覆盖率安全性的新功能,以确保您不会破坏任何现有功能.