【发布时间】:2012-02-21 17:29:42
【问题描述】:
tl;dr:跳到最后一段
最近我一直在尝试使用 RSpec 的 request specs 来做一些更有针对性的测试。
这是我的测试的主要外观:
- 一般黄瓜功能规范,即用户发表评论,对评论投赞成票,作者获得积分
-
模型规格,当模型实际具有某些功能时,即
User#upvote(comment) - 控制器规范,我在其中存根大部分内容,并尝试确保代码按我预期的方式运行
- 查看规范,当视图中有复杂内容时,例如仅在用户尚未投票时才呈现 upvote 链接,并且这些链接也会被存根李>
问题是当我遇到一些导致错误的特定场景时,一切似乎都在我无法重现的模型/视图层中工作。
这迫使我编写集成测试,我也可以在 Cucumber 中完成。一旦我能够真正重现它,问题就会出现,我需要弄清楚它为什么会发生。这通常意味着在测试中玩耍,改变不同的东西,看看会发生什么。
例如创建一个评论,该评论归试图投票的用户所有,尝试用过期的会话进行投票等。然而,用 Cucumber 编写这些真的很痛苦,因为需要编写一个场景,然后指定每个步骤。
在这一点上,我更喜欢写一个请求规范,因为它更底层并且允许我直接做一些事情。问题是,我不确定如何正确编写请求规范,或者规则是什么。
这里有一个简单的例子:
visit login_path
fill_in "Username", :with => user.username
fill_in "Password", :with => user.password
click_button "Log in"
对
post sessions_path(:username => user.username, :password => user.password)
甚至是更底层的东西,比如
session[:user_id] = user.id # this actually doesn't work, but the idea is there
这两个示例都实现了相同的目标,它们将登录用户。我知道选择哪个答案取决于我需要测试的内容,但这并不能回答正确的传统方法这样做。
我一直在尝试查找有关请求规范的信息,但在任何地方都没有真正描述它们。 The RSpec book 没有覆盖它们,the RSpec documentation 也没有说什么。
编写请求规范的正确方法是什么?我什么时候应该使用 capybara,什么时候应该只使用 Rails 的 #get 和 #post 方法而不是单击按钮和 visiting 路径?
【问题讨论】:
-
集成(又名请求)规范应该模仿用户的行为,所以我通常坚持使用 Capybara 的助手(访问/填充,点击等...)。但是,这并不是冻结和规则被打破(故意)。见relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec。请注意,我不使用 Cucumber。
-
我在测试控制器的行为时使用标准的 get/post 请求测试。例如,当我说某些内容应该只显示给管理员时。在我的规范中,我对管理员进行身份验证并验证该选项是否在正文中。我不点击/访问。我唯一一次使用点击和访问的东西是当视图中有一些逻辑时,比如 jquery。否则,视图代码应该是微不足道的。因此,在您支持自己的评论示例中,我将使用帮助程序构建用户,为该用户构建评论,然后发布请求说 /upvote 并说“它应该返回 403”
-
我使用模型/视图/控制器测试来测试代码,水豚(或黄瓜和..)来测试用户交互(或所有组件的集成)。我可以使用请求规范来测试路由/控制器集成),我认为这就是它的目的,但在我看来它不是必需的。如果您没有集成测试,您需要的请求测试。例如,如果你只写一个只有机器交互的 api,那么你可以使用解决方案 II,否则我会使用解决方案 capybara。
标签: ruby-on-rails ruby ruby-on-rails-3 rspec rspec2