单元测试是否应测试所有通过条件以及所有失败条件?
例如,假设我有一个测试Widget_CannotActiveWidgetIfStateIsCancelled
。
让我们说有100种可能的状态。
我可以逃避测试只有在State == Cancelled时我无法激活我的小部件,或者我是否还需要测试我是否可以在其他99个状态中激活它?
是否有一些妥协可以让我避免花费所有时间编写测试? :)
答案 0 :(得分:3)
您似乎在询问您的测试是否应该详尽:您是否应该测试所有可能的状态。答案是响亮的不,原因很简单,即使简单的代码也可能有太多的状态。即使是小型程序也可以拥有比可测试的更多潜在状态,即使你从大爆炸以来一直使用过它。
您应该使用 equivalence partitioning :识别状态组,以便组中的所有状态可能具有相似的行为,然后每组有一个测试用例。
如果您这样做,您可能会发现只需要两个测试用例。
答案 1 :(得分:1)
在这种情况下,您希望使用一个参数化测试,该测试将所有99个值作为输入。
使用xUnit.net,这可能看起来像这样(未经测试,可能包含小编译错误):
[Fact]
public void Widget_CannotActiveWidgetIfStateIsCancelled()
{
// Arrange ...
sut.State = State.Cancelled;
Assert.False(sut.CanActivate);
}
[Theory, ValidStatesData]
public void Widget_CanActivateWidgetIfStateIsNotCancelled(State state)
{
// Arrange ...
sut.State = state;
Assert.True(sut.CanActivate);
}
private class ValidStatesDataAttribute : DataAttribute
{
public override IEnumerable<object[]> GetData(
MethodInfo methodUnderTest, Type[] parameterTypes)
{
return Enum.GetValues(typeof(State))
.Cast<State>()
.Except(new [] { State.Cancelled })
.Select(x => new object[] { x });
}
}
答案 2 :(得分:1)
如果您正在使用NUnit,则可以使用attributes,因此您只需编写一个测试代码,但可以测试所有100个值。