Ruby on rails 什么';在RSpec中编写请求规范的正确方法是什么?

Ruby on rails 什么';在RSpec中编写请求规范的正确方法是什么?,ruby-on-rails,ruby,ruby-on-rails-3,rspec,rspec2,Ruby On Rails,Ruby,Ruby On Rails 3,Rspec,Rspec2,tl;博士:跳到最后一段 最近我一直在尝试使用RSpec的请求规范来做一些更有针对性的测试 我的测试主要是这样的: 通用黄瓜特性规范,即用户带评论进入帖子,对评论进行投票,作者获得分数 模型规格适用于模型实际具有某种功能的情况,即用户投票(评论) 控制器规范我在其中存根了大部分内容,只是尝试确保代码按照我预期的方式运行 视图规格适用于视图中存在复杂内容的情况,例如仅当用户尚未向上投票时才呈现向上投票链接,并且这些规格也被存根化 问题是当我有一些特定的场景导致一个bug,并且在模型/视图层中一

tl;博士:跳到最后一段

最近我一直在尝试使用RSpec的请求规范来做一些更有针对性的测试

我的测试主要是这样的:

  • 通用黄瓜特性规范,即用户带评论进入帖子,对评论进行投票,作者获得分数
  • 模型规格适用于模型实际具有某种功能的情况,即
    用户投票(评论)
  • 控制器规范我在其中存根了大部分内容,只是尝试确保代码按照我预期的方式运行
  • 视图规格适用于视图中存在复杂内容的情况,例如仅当用户尚未向上投票时才呈现向上投票链接,并且这些规格也被存根化
问题是当我有一些特定的场景导致一个bug,并且在模型/视图层中一切似乎都正常工作时,我无法重现它

这迫使我编写一个集成测试,我也可以在cucumber中这样做。一旦我能够真正复制它,问题就出现了,我需要弄清楚它为什么会发生。这通常意味着在测试中玩转,改变不同的事情,看看会发生什么

例如,创建一条评论,该评论归试图升级投票的用户所有,尝试使用过期会话进行投票等。然而,使用Cumber编写这些评论确实非常痛苦,因为需要编写一个场景,然后指定每个步骤

在这一点上,我更喜欢编写一个请求规范,因为它更低级,允许我直接做一些事情。问题是,我真的不确定如何正确地编写请求规范,或者规则是什么

这里有一个简单的例子:

visit login_path
fill_in "Username", :with => user.username
fill_in "Password", :with => user.password
click_button "Log in"
vs

或者更低级的东西,比如

session[:user_id] = user.id # this actually doesn't work, but the idea is there
这两个示例实现了相同的功能,它们将让用户登录。我知道选择哪一个答案取决于我需要测试的内容,但这并不是正确的、传统的方法

我一直在试图找到一些关于请求规范的东西,但是它们在任何地方都没有被真正描述。不包括他们,也不说什么


编写请求规范的正确方法是什么?我应该什么时候使用水豚,什么时候只使用Rails的get和post方法,而不是点击按钮和访问路径?

对于请求规范,我相信惯例是坚持测试用户行为和界面交互,这意味着加载页面,填写表单等。网站用户无法设置会话或直接与变量交互,因此您也不应请求规范

我经常试图通过在请求规范中发布或设置变量来跳过页面加载和表单交互(为了提高速度,尤其是繁重的ajax规范),但这确实违背了请求规范的目的

正如前面提到的注释,您应该在其他规范类型中测试特定的控制器/视图行为。

Sarmon first。。。。 我认为你这个测试作者的自然发展是:

  • 控制器
  • 模型
  • 请求
  • 请求、控制器和型号规格的混合
  • 我知道我首先开始看控制器,因为它更容易掌握

    然后你进入模型规格,对于非快乐路径的事情

    然后你意识到rspec实际上并没有渲染视图,所以你开始在Airbrake中看到愚蠢的错误,所以你说,射击。。。我需要测试视图和工作流。因此要求规格

    最后,随着年龄的增长,你会意识到,这三项都很重要,应该少用,但也要相应地使用。我现在只是在第四步。。。请求规格太多,在一个中等大小的应用程序上,整个套件需要花费5分钟的时间。糟透了

    回答你的问题: 我在请求规范中使用capybara测试工作流和需要“查看”的视图(使用
    page.should
    或任何棘手的JS(例如jquery ui选择器)

    如果我只需要确保控制器变量被实例化,或者为了一个不愉快的路径快速发布一些东西,工作流之外的事情…我使用控制器。例如,在paypal中发布到IPN控制器

    你会惊讶于它涵盖了这么多。这让你需要测试所有边缘案例所需要的所有损坏的东西的模型


    老实说,尽管如此,我还是要说使用夹具和测试单元进行集成测试…仍然喜欢它们更好、更快、更强…等等。

    集成(又称请求)规范应该模仿用户的行为,因此我通常会使用水豚的助手(访问/填写、单击等)。但这并不是说冻结和打破规则(故意)。请参阅。注意,我没有使用Cucumber。当我测试控制器的行为时,我使用标准的get/post请求测试。例如,当我说某个内容应该只显示给管理员时。在我的规范中,我对管理员进行身份验证,并验证选项是否在正文中。我不进行单击/访问。我唯一一次使用单击和访问g stuff是当视图中有一些逻辑时,比如jquery。否则视图代码应该是微不足道的。因此,在您自己的注释升级示例中,我将使用助手构建一个用户,为该用户创建一个注释,然后发布一个请求,说/upvote并说“it should return 403”,我使用模型/视图/控制器测试来测试代码,capybara(或Cumber和..)来测试用户交互(或所有组件的集成)。我可以使用请求规范来测试路由/控制器集成),我认为这就是它的目的,但在我看来,这是不必要的。如果没有集成测试,则需要进行请求测试。例如,如果只编写一个只有机器交互的api,则可以使用解决方案II,否则我将使用解决方案capybara。就我个人而言,我不这么认为
    session[:user_id] = user.id # this actually doesn't work, but the idea is there