如何在不违反单一职责原则的情况下编写类似的测试用例

本文关键字:情况下 测试用例 原则 单一职 | 更新日期: 2023-09-27 18:01:39

我已经为不同的输入创建了一个单元测试,以确保输出是正确的。

[TestMethod]
    public void CountInversionTest()
    {
        #region Arrange
        int[] sourceArray = {4, 3, 2, 1};
        int correctInversionCount = 6;
        int[] sourceArray2 = { 1, 3, 5, 2, 4, 6};
        int correctInversionCount2 = 3;
        int[] sourceArray3 = { 5, 6, 2, 3, 1, 4, 7 };
        int correctInversionCount3 = 10;
        #endregion
        #region Act
        Sorter sorter = new Sorter();
        int inversionCount = sorter.CountInversion(sourceArray);
        int inversionCount2 = sorter.CountInversion(sourceArray2);
        int inversionCount3 = sorter.CountInversion(sourceArray3);
        #endregion
        #region Assert
        Assert.AreEqual(correctInversionCount, inversionCount);
        Assert.AreEqual(correctInversionCount2, inversionCount2);
        Assert.AreEqual(correctInversionCount3, inversionCount3);
        #endregion
    }

由于案例非常相似,我将它们放在一个测试方法中。这种行为是可以的还是违反了单一责任原则?如果它违反了SRP,那么什么是更好的解决方案?

如何在不违反单一职责原则的情况下编写类似的测试用例

使用适当的单元测试框架(如xUnit.net),您可以编写参数化测试:

[Theory]
[InlineData(new[] { 4, 3, 2, 1 }, 6)]
[InlineData(new[] { 1, 3, 5, 2, 4, 6 }, 3)]
[InlineData(new[] { 5, 6, 2, 3, 1, 4, 7 }, 10)]
public void ParameterizedCountInversionTest(int[] input, int expected)
{
    Sorter sut = new Sorter();
    var actual = sut.CountInversion(input);
    Assert.Equal(expected, actual);
}

这将运行三个测试,而不是一个,让您更好地了解哪个特定的测试用例失败了(如果有任何失败的话)。

这样的测试也更可读。

NUnit也有这个功能,但是MSTest没有(上次我看)。

单一职责原则告诉我们这个方法应该只有一个改变的原因。因此,单元测试应该测试一个方法,并且应该只在被测方法发生变化时才进行更改。这是CountInversion()法。CountInversion()方法是否会发生变化,使得其中一个sourceArray输入必须改变,而其他输入不变?在这种情况下,输入应该被分割成单独的测试,以适应SRP。

一般来说,一个单元测试可以使用不同的输入多次调用被测方法。正如@itsme86所评论的,测试框架通常通过向单元测试传递参数来促进这种行为。

我决定回答我自己的问题

所以我没有使用任何第三方框架或库进行测试,而是使用默认的MSTest。我最后做了这个

    [TestMethod]
    public void CountInversionTestCase1()
    {
        CountInversionTest(new int[] { 4, 3, 2, 1 }, 6);
    }
    [TestMethod]
    public void CountInversionTestCase2()
    {
        CountInversionTest(new int[] { 1, 3, 5, 2, 4, 6 }, 3);
    }
    [TestMethod]
    public void CountInversionTestCase3()
    {
        CountInversionTest(new int[] { 5, 6, 2, 3, 1, 4, 7 }, 10);
    }
    public void CountInversionTest(int[] sourceArray, int expectedInversionCount)
    {
        #region Act
        Sorter sorter = new Sorter();
        long actualInversionCount = sorter.CountInversion(sourceArray);
        #endregion
        #region Assert
        Assert.AreEqual(expectedInversionCount, actualInversionCount);
        #endregion
    }

这不是最好的解决方案,但它满足了需求,并且不使用任何第三方库。我希望这对大家有所帮助。