BDD 示例 - 为什么要测试“快乐路径”?仅有的?

发布于 2024-08-15 18:17:38 字数 779 浏览 2 评论 0原文

我偶然发现了一个旧的 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 的密码是否无效并触发相应的错误。 “快乐路径”测试也会在那里,但不像文章中那样单独存在。

你有什么意见?我只是想弄清楚这个人为什么这样做,以及他是否只是忽视了这个问题,或者这是他的意图。我可能错过了一些东西。

I've accidentally stumbled upon an old article by Luke Redpath that presents a very simple BDD example (very short and easy to follow even for non-Ruby programmers like me). I found the end result very incomplete, thus making the example pretty useless.

The end result is a single test which verifies that a user with preset attributes is valid. In my view, this is simply not enough to verify the validation rules correctly. For example, if you change

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

to

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

(or even remove password length validation completely) the test will still pass, but you can obviously see the code is now violating the initial requirements.

I just think the last refactoring of putting all the individual tests into a single one is simply not enough. He tests only the "happy path" which doesn't guarantee much. I would absolutely have all the tests that verify that the correct error is triggered with certain values. In the case of the password, I would test that a password of length less than 6 and greater than 12 is invalid and triggers the appropriate error. The "happy path" test would be there as well, but not alone by itself as it's in the article.

What's your opinion? I'm just trying to figure out why the guy did it the way he did and whether he simply overlooked the problem or it was his intention. I may be missing something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盛夏已如深秋| 2024-08-22 18:17:38

我不太明白你的问题。规范do包含对密码长度的期望,无论是对于幸福路径还是两种不同的失败模式(密码太长和密码太短):

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 个字符),但这还不算太糟糕。

I don't quite understand your question. The specs do contain expectations about the password lenght, both for the happy path and the two different failure modes (password too long and password too short):

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

This takes care of the happy path, since valid_user_attributes contains a valid password.

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

And this tests the two failure modes.

Granted, there is one boundary case missing (12 characters), but that's not too bad.

小梨窩很甜 2024-08-22 18:17:38

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

I don't have time to read the article, so I can't verify your claims, but the general answer in my opinion is that if the password validation rule is a concrete requirement, it should be verified with one or more tests for that specific requirement (at least one per "part" of the requirement).

無心 2024-08-22 18:17:38

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

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

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

那么我们将编写测试数据来进行通过我们错误解释的测试。因此编写更多的测试只会给我们带来错误的信心。这就是为什么 TDD 和 BDD 的支持者也青睐其他 XP 技术,例如结对编程:捕获我们在单元测试中引入的错误。

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

BDD (and TDD) are design activities. The tests are meant to drive the design of the code, not guarantee that it is completely bug-free. There should be independent testers for that. So we need a decent degree of coverage, to ensure that our code works as expected and handles exceptions in a clean fashion. But TDD doesn't demand that we write unit tests for every conceivable edge case.

With regard to the specific example you cite, perhaps he should have coded two tests, one with a password of six characters, one with a passowrd of twelve characters. But what would be the point? We know that the requirement is the password must be between six and twelve characters in length. If we have misunderstood the requirements and think the rule ought to be ...

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

... then we're going to write our test data to make a test which passes our incorrect interpretation. So writing more tests would only give us misplaced confidence. That's why proponents of TDD and BDD favour other XP techniques like pair programming as well: to catch the errors we introduce into our unit tests.

Similarly, we could remove the test validating the password length altogether, but what would be the point? The tests are there to help us correctly implement the spceification. If we don't have tests for every piece of code we write then we are not doing TDD/BDD.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文