我应该真的测试控制器吗?

时间:2011-05-25 19:21:22

标签: ruby-on-rails ruby rspec bdd

我正在努力获得最佳的codecoverage /开发时间结果

目前我使用rspec + shoulda来测试我的模型和rspec + capybara来编写我的验收测试。

我尝试为一个简单的crud写一个控制器测试,但它花了太长时间,最后我得到了一个令人困惑的测试(我可能不好)

使用rspec进行控制器测试的最佳实践是什么?

以下是我的测试和控制器的要点(一个测试尚未通过):

https://gist.github.com/991687 https://gist.github.com/991685

7 个答案:

答案 0 :(得分:15)

我认为这种方式是验收测试(即Cucumber / Capybara),测试用户通常在应用程序上执行的交互。这通常包括用户可以使用有效数据创建特定资源,然后如果他们输入无效数据,他们会看到错误。控制器测试更多的是用户不能能够正常执行的操作,或者是使用Cucumber进行测试时非常麻烦的极端边缘情况。

通常当人们编写控制器测试时,他们会有效地测试同样的事情。在控制器测试中测试控制器方法的唯一原因是边缘情况。

边缘情况,例如,如果用户向展示页面输入无效ID,则应显示404页面。这是一个非常简单的事情来测试控制器测试,我建议这样做。你想确保当他们点击动作时他们收到了404响应,繁荣,简单。

确保您的new操作成功响应并且没有语法错误?请。这就是你的黄瓜功能会告诉你的。如果该操作突然发生哎呀案例,您的功能将会中断,然后您将解决该问题。

另一种思考方式是你想测试一个特定的动作以某种方式响应(即控制器测试),还是你更关心用户是否可以进行new动作完成创建该资源的整个动作(即验收测试)?

答案 1 :(得分:13)

也许没有。

当然,您可以为您的控制器编写测试。它可能有助于编写更好的控制器但是如果你的控制器中的逻辑很简单,那么你的控制器测试就不是赢得战斗的地方。

我个人更喜欢经过良好测试的模型和一套完整的集成(验收)测试,而不是控制器测试。

那就是说,如果你有麻烦为控制器编写测试,那么然后 做测试。至少在你掌握它之前。然后决定是否要继续。每种测试也是如此:尝试直到你理解它为止,然后再决定。

答案 2 :(得分:6)

编写控制器测试可以让您的应用程序对您撒谎。一些原因:

  • 控制器测试不会在它们运行的​​环境中执行。即它们不在机架中间件堆栈的末尾,所以在使用设备时用户之类的东西不可用(作为一个简单的例子)。随着Rails更多地转向基于机架的设置,使用了更多的机架中间件,并且您的环境越来越偏离“单元”行为。
  • 您没有测试应用程序的行为,您正在测试实现。通过嘲讽和抄袭您的方式,您将以规范形式重新实施实施。一个简单的方法来判断你是否这样做;如果你没有改变url响应的预期行为,但确实改变了控制器的实现(甚至可能映射到不同的控制器),你的测试是否会中断?如果他们这样做,那么你就是在测试实现而不是行为。你也正在设置自己被骗。当你存根和模拟时,不能保证你设置的模拟或存根做你认为他们做的事情,或者即使重构后他们假装存在的方法也存在。
  • 通过您的应用程序'public'api无法调用控制器方法。到访控制器的唯一方式是通过堆栈和路由。如果你不能通过网址从请求中删除它,它真的坏了吗?

我使用我的测试来保证我的应用程序在部署时不会中断。控制器测试没有增加我对我的应用确实功能的信心,实际上他们的存在降低了我的信心。

另一个例子,在测试应用程序的“行为”时,您是否关心特定文件模板已呈现,或者是否引发了某个异常,或者是应用程序将某些内容返回到具有特定状态代码的客户端?

测试控制器(或视图)会增加您对自己施加的测试负担,并且意味着重构成本高于其需要的成本,因为可能会破坏测试。

答案 3 :(得分:2)

你应该测试吗?是

有些宝石可以让测试控制器更快

http://blog.carbonfive.com/2010/12/10/speedy-test-iterations-for-rails-3-with-spork-and-guard/

答案 4 :(得分:2)

绝对测试控制器。一些痛苦的经验法则:

  • 模拟出模型对象
  • 控制器操作使用的存根模型对象方法
  • 牺牲了很多鸡。

答案 5 :(得分:2)

我喜欢对每个控制器方法进行测试,至少只是为了消除可能导致页面爆炸的愚蠢语法错误。

答案 6 :(得分:1)

许多人似乎正朝着使用Cucumber进行集成测试而不是编写控制器和路由测试的方法发展。