单元测试彻底性 - 测试通过条件以及失败条件?

时间:2013-09-04 16:39:50

标签: unit-testing

单元测试是否应测试所有通过条件以及所有失败条件?

例如,假设我有一个测试Widget_CannotActiveWidgetIfStateIsCancelled

让我们说有100种可能的状态。

我可以逃避测试只有在State == Cancelled时我无法激活我的小部件,或者我是否还需要测试我是否可以在其他99个状态中激活它?

是否有一些妥协可以让我避免花费所有时间编写测试? :)

3 个答案:

答案 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个值。