3

我有一个(许多)具有属性的类。有些有逻辑,有些没有。假设我想测试这些属性,我该怎么做呢?

最近,我对创建单元测试的 BDD 风格很感兴趣。

这里这里

所以我会设置上下文 - 基本上创建 SUT 并加载所需的任何内容。然后在每个观察(测试方法)中,我会验证一个特定的属性是否包含它应该包含的内容。

这是我的问题。如果 SUT 有 20 个属性,那么我要创建 20 个观察/测试吗?如果其中一个属性包含更有趣的逻辑,我猜可能会更多。

[Observation]
public void should_load_FirstName()
{
    Assert.Equals<string>("John", SUT.FirstName);
}

[Observation]
public void should_load_LastName()
{
    Assert.Equals<string>("Doe", SUT.LastName);
}

[Observation]
public void should_load_FullName()
{
    Assert.Equals<string>("John Doe", SUT.FullName);
}

但是,如果在一次观察中聚合简单的那些会更好吗?

[Observation]
public void should_load_properties()
{
    Assert.Equals<string>("John", SUT.FirstName);
    Assert.Equals<string>("Doe", SUT.LastName);
    Assert.Equals<string>("John Doe", SUT.FullName);
}

或者如果我使用自定义属性(可以多次应用于方法)怎么办。这样我就可以做到,例如:

[Observation(PropertyName="FirstName", PropertyValue="John")]
[Observation(PropertyName="LastName", PropertyValue="Doe")]
[Observation(PropertyName="FullName", PropertyValue="John Doe")]
public void should_load_properties()
{
}
4

2 回答 2

4

一般来说,您应该在每个测试只有一个逻辑断言之后努力。优秀的书xUnit Test Patterns对此进行了很好的讨论,但重点是如果测试失败的原因只有一个,它可以更容易地理解违规发生的位置。与 BDD 相比,这可能与回归测试更相关,尽管......

所有这一切都意味着您选择编写一个验证所有属性的单个测试可能是最没有吸引力的,尽管您可能会争辩说验证所有属性是一个单一的逻辑断言......

xDD(TDD、BDD 等)的一个更核心的原则是测试应该充当Executable Specifications。换句话说,当您查看测试时,不仅要测试的是什么,而且要知道为什么预期值是这样的,应该立即清楚。在您的示例中,尚不清楚为什么 SUT.FirstName 应为“John”而不是“Jane”。

如果可能的话,我会编写这些测试以使用派生值而不是硬编码值。

对于可写属性,我经常编写测试来简单地验证 getter 返回分配给 setter 的值。

对于只读属性,我经常编写测试来验证该值是否与构造函数参数匹配。

这样的测试可以封装成可重用的测试代码,封装了常见的测试习惯。我目前正在开发一个可以做到这一点的图书馆

于 2009-10-09T08:25:12.577 回答
0

查看其他 SubSpec 语法(示例)——在这种情况下,末尾的[Specification]每个s 都代表测试的单独执行。Assert我最初将语法视为 lambda 滥用,但现在我已经使用它一段时间了。

于 2010-04-13T08:15:44.890 回答