组织单元测试:课程类别或行为?从哪儿开始?

时间:2014-03-16 03:04:30

标签: c# unit-testing organization code-organization

  

摘要

我编写了一个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)

这听起来不太好。

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

或者,我保持每个类的一个测试文件的旧方式为这个...

1 个答案:

答案 0 :(得分:2)

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

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