1

我偶然发现了 Luke Redpath 的一篇旧文章,其中介绍了一个非常简单的 BDD 示例(即使对于像我这样的非 Ruby 程序员来说也非常简短且易于理解)。我发现最终结果非常不完整,因此使示例变得毫无用处。

最终结果是验证具有预设属性的用户是否有效的单个测试。在我看来,这根本不足以正确验证验证规则。例如,如果您更改

validates_length_of :password, :in => 6..12, :allow_nil => :true

validates_length_of :password, :in => 7..8, :allow_nil => :true

(甚至完全删除密码长度验证)测试仍然会通过,但您显然可以看到代码现在违反了初始要求。

我只是认为将所有单独的测试放在一个单独的测试中的最后一次重构是不够的。他只测试不能保证太多的“快乐路径”。我绝对会有所有的测试来验证正确的错误是由某些值触发的。在密码的情况下,我会测试长度小于 6 且大于 12 的密码无效并触发相应的错误。“幸福路径”测试也将在那里,但并不像文章中那样单独存在。

你怎么看?我只是想弄清楚为什么这个人会这样做,以及他是否只是忽略了问题或者这是他的意图。我可能会遗漏一些东西。

4

3 回答 3

1

我不太明白你的问题。规范确实包含对密码长度的期望,包括快乐路径两种不同的失败模式(密码太长和密码太短):

specify "should be valid with a full set of valid attributes" do
  @user.attributes = valid_user_attributes
  @user.should_be_valid
end

valid_user_attributes因为包含有效密码,所以这会照顾好路径。

specify "should be invalid if password is not between 6 and 12 characters in length" do
  @user.attributes = valid_user_attributes.except(:password)
  @user.password = 'abcdefghijklm'
  @user.should_not_be_valid
  @user.password = 'abcde'
  @user.should_not_be_valid
end

这测试了两种故障模式。

当然,缺少一个边界情况(12 个字符),但这还不错。

于 2009-12-21T23:58:04.403 回答
0

BDD(和 TDD)是设计活动。测试旨在推动代码的设计,而不是保证它完全没有错误。应该有独立的测试人员。所以我们需要相当程度的覆盖率,以确保我们的代码按预期工作并以干净的方式处理异常。但是 TDD 并不要求我们为每个可能的边缘情况编写单元测试。

关于您引用的具体示例,也许他应该编写两个测试,一个使用六个字符的密码,一个使用十二个字符的密码。但有什么意义呢?我们知道要求是密码长度必须在六到十二个字符之间。如果我们误解了要求并认为规则应该是......

validates_length_of :password, :in => 7..8, :allow_nil => :true

...然后我们将编写我们的测试数据以进行通过我们错误解释的测试。所以写更多的测试只会给我们错误的信心。这就是为什么 TDD 和 BDD 的支持者也支持其他 XP 技术(如结对编程)的原因:捕捉我们在单元测试中引入的错误。

同样,我们可以完全删除验证密码长度的测试,但重点是什么?这些测试可以帮助我们正确实施规范。如果我们没有对我们编写的每一段代码进行测试,那么我们就不是在做 TDD/BDD。

于 2009-12-21T13:43:11.913 回答
0

我没有时间阅读这篇文章,因此无法验证您的说法,但我认为一般的答案是,如果密码验证规则是一项具体要求,则应通过一项或多项测试对其进行验证特定要求(要求的每个“部分”至少一项)。

于 2009-12-21T13:14:50.787 回答