1

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

例如,假设我有一个 test Widget_CannotActiveWidgetIfStateIsCancelled

假设有 100 种可能的状态。

我可以只测试当状态 == 取消时我无法激活我的小部件,还是我还必须测试我可以在其他 99 个状态中激活它吗?

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

4

3 回答 3

3

您似乎在问您的测试是否应该详尽无遗:您是否应该测试所有可能的状态。答案是否定的,原因很简单,即使是简单的代码也可能有太多的状态。即使是小程序也可能具有比可测试更多的潜在状态,即使您自大爆炸以来一直使用这些状态。

您应该改为使用等价分区:识别状态组,以便组中的所有状态都可能具有相似的行为,然后每组有一个测试用例。

如果你这样做,你可能会发现你只需要两个测试用例。

于 2013-09-04T19:56:20.673 回答
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 });
    }
}
于 2013-09-04T16:44:23.583 回答
1

如果您使用 NUnit,则可以使用属性,因此您只需编写一个测试代码,但可以测试所有 100 个值。

于 2013-09-04T16:44:56.047 回答