单元测试生成不同字符串的类

时间:2010-07-22 14:59:15

标签: c# unit-testing

我正在尝试为生成不同字符串的类编写单元测试。我最初的反应如下:

public void GeneratedStringsShouldBeDistinct()
{
    UniqueStringCreator stringCreator = new UniqueStringCreator();
    HashSet<string> generatedStrings = new HashSet<string>();
    string str;

    for (int i = 0; i < 10000; i++)
    {
        str = stringCreator.GetNext();
        if (!generatedStrings.Add(str))
        {
            Assert.Fail("Generated {0} twice", str);
        }
    }
}

我喜欢这种方法,因为我知道底层算法并没有使用任何随机性,所以我不会遇到可能会失败一次然后接下来会成功的情况 - 但是未来可能会被某人交换掉。 OTOH,任何随机算法的测试会导致这种类型的测试不一致,那么为什么不这样做呢?

我应该只获得2个元素并检查清晰度(使用0/1 /多元哲学)?

还有其他意见或建议吗?

4 个答案:

答案 0 :(得分:1)

我会继续使用你的方法;它可能是最可靠的选择。

顺便说一句,您不需要if声明:

Assert.IsTrue(generatedStrings.Add(str), "Generated {0} twice", str);

答案 1 :(得分:0)

如果我想测试依赖于随机输入的代码,我会尝试删除随机生成(例如,ITestableRandomGenerator),以便可以模拟它进行测试。然后,您可以注入不同的“随机”序列,这些序列可以适当地触发被测代码的不同执行路径,并保证必要的代码覆盖率。

您展示的特定测试基本上是一个黑盒测试,因为您只是生成输出并验证它至少可以运行N个周期。由于代码没有任何输入,这是一个合理的测试,但如果您知道不同的条件可能会影响您的算法,以便您可以测试这些特定的输入可能会更好。这可能意味着以某种方式运行具有不同“种子”值的算法,选择种子以便它以不同的方式运用代码。

答案 2 :(得分:0)

如果您将算法传递给UniqueStringCreator的构造函数,则可以在单元测试中使用存根对象来生成伪随机(可预测)数据。另见战略模式。

答案 3 :(得分:0)

如果在类中有某种检查,你总是可以将检查清晰度的部分与生成字符串的部分分开。

然后你嘲笑检查器,并测试两个上下文中的行为;检查器认为已经创建了一个字符串的那个,以及没有创建字符串的那个。

无论底层实现逻辑如何,您都可以找到类似的方法来分担职责。

否则,我同意SLaks - 坚持你所拥有的。进行测试的主要原因是代码保持易于更改,因此只要人们可以阅读并思考,“哦,它在做什么!”你可能很好。