组织单元测试:班级还是行为测试?从哪里开始

本文关键字:测试 开始 单元测试 | 更新日期: 2023-09-27 17:50:31

摘要

我已经编写了一个RandomValues类,它提供了多种方法来生成每个值类型的随机值。这个静态类稍后将用作单元测试其他项目类的工具。

我以TDD的方式对每个方法进行了单元测试。

现在,我看到可以进行一些重构来促进代码重用,这让我在搜索了互联网上不同类型的结果后提出了这个问题。其中,有一个吸引了我的注意力。

Structuring Unit Tests

除此之外,我真的很喜欢以这样的行为方式构建单元测试的想法:

Behavioral

现在,我想知道如何将此应用于我的案例。

RandomValuesTests

[TestFixture]
public class RandomValuesTest {
    [Test]
    public void RandomInt_ReturnsRandomIntegerValues() {
        int unexpected = RandomValues.RandomInt();
        int actual = RandomValues.RandomInt();
        Assert.AreNotEqual(unexpected, actual);
    } 
    [Test]
    public void RandomInt_ReturnsInRangeIntegerValues() {
        int minValue = 12;
        int maxValue = 20;
        int actual = RandomValues.RandomInt(minValue, maxValue);
        Assert.IsTrue(minValue <= actual && actual <= maxValue);
    }
    [Test]
    public void RandomDateTime_ReturnsRandomDateTimeValues() {
        DateTime unexpected = RandomValues.RandomDateTime();
        DateTime actual = RandomValues.RandomDateTime();
        Assert.AreNotEqual(unexpected, actual);
    }
    [Test]
    public void RandomDateTime_ReturnsInRangeIntegerValues() {
        DateTime minValue = new DateTime(2000, 1, 1);
        DateTime maxValue = new DateTime(2000, 12, 31);
        DateTime actual = RandomValues.RandomDateTime(minValue, maxValue);
        Assert.IsTrue(minValue <= actual && actual <= maxValue);
    }
    [Test]
    public void RandomEnum_ReturnsRandomEnumValues() {
        RandomValuesEnum unexpected = RandomValues.RandomEnum<RandomValuesEnum>();
        RandomValuesEnum actual = RandomValues.RandomEnum<RandomValuesEnum>();
        Assert.AreNotEqual(unexpected, actual);
    }
}

RandomValues

public static class RandomValues {
    public static int RandomInt() { return RandomInt(int.MinValue, int.MAxValue); }
    public static int RandomInt(int minValue, int maxValue) {
        return generator.Next(minValue, maxValue);
    }
    // And the other Random[Type] here...
    private static Random generator = new Random();
}

进一步思考

我曾想过使用一个基类来组织我的测试,该基类将提供两个抽象方法:ReturnsRandomValuesReturnsInRangeRandomValues,并按类型创建一个测试类来覆盖这两个方法,如下所示。

RandomValuesTestBase<T>

public abstract class RandomValuesTestBase<T> where T : IComparable<T> {
    public abstract void ReturnsRandomValues();
    public abstract void ReturnsInRangeRandomValues(T minValue, T maxValue);
}
[TestFixture]
public class RandomInt : RandomValuesTestBase<int> {
    [Test]
    public override void ReturnsRandomValues() {
        // Use the same code as shown above for RandomInt_Returns...
    }
    [TestCase(10, 20)]
    public override void ReturnsInRangeRandomValues(int minValue, int maxValue) {
        // Use the same code as shown above for RandomInt_ReturnsInRange...
    }       

}

但是,我必须为每种类型创建一个测试类:boolbytechar。。。

Built-In Types Table (C# Reference)

这听起来一点都不好。

我现在正试图弄清楚如何从总结中提到的两个参考文献开始,并从中建立一个可行的组织

或者,我保留了这个类的每个类一个测试文件的简单方式。。。

组织单元测试:班级还是行为测试?从哪里开始

我个人不会担心在这里让测试变得通用或抽象。我认为RandomValues类支持的每种类型都需要自己的一组测试,并且可能会以不同的方式实现。

我认为重要的部分是RandomValues类的功能是使用测试优先的方法实现的。首先,你为随机整数编写测试,然后是DateTimes,等等。我认为你编写的测试简单、干净、易于理解。