组织单元测试:班级还是行为测试?从哪里开始
本文关键字:测试 开始 单元测试 | 更新日期: 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();
}
进一步思考
我曾想过使用一个基类来组织我的测试,该基类将提供两个抽象方法:ReturnsRandomValues
和ReturnsInRangeRandomValues
,并按类型创建一个测试类来覆盖这两个方法,如下所示。
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...
}
}
但是,我必须为每种类型创建一个测试类:bool
、byte
、char
。。。
Built-In Types Table (C# Reference)
这听起来一点都不好。
我现在正试图弄清楚如何从总结中提到的两个参考文献开始,并从中建立一个可行的组织
或者,我保留了这个类的每个类一个测试文件的简单方式。。。
我个人不会担心在这里让测试变得通用或抽象。我认为RandomValues
类支持的每种类型都需要自己的一组测试,并且可能会以不同的方式实现。
我认为重要的部分是RandomValues
类的功能是使用测试优先的方法实现的。首先,你为随机整数编写测试,然后是DateTimes,等等。我认为你编写的测试简单、干净、易于理解。