简体   繁体   English

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

[英]Should I really test controllers?

I'm trying to get the best codecoverage/development time result我正在尝试获得最佳的代码覆盖率/开发时间结果

Currently I use rspec+shoulda to test my models and rspec+capybara to write my acceptance tests.目前我使用 rspec+shoulda 来测试我的模型和 rspec+capybara 来编写我的验收测试。

I tried writing a controller test for a simple crud but it kinda took too long and I got a confusing test in the end(my bad probably)我尝试为一个简单的杂物编写 controller 测试,但它花了太长时间,最后我得到了一个令人困惑的测试(我可能不好)

What`s the best pratice on controller testing with rspec?使用 rspec 进行 controller 测试的最佳实践是什么?

Here is a gist on my test and my controller(one test does not pass yet):这是我的测试和控制器的要点(一个测试尚未通过):

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

The way I view this is that acceptance tests (ie Cucumber / Capybara), test the interactions that a user would normally perform on the application.我认为这是验收测试(即 Cucumber / Capybara),测试用户通常会在应用程序上执行的交互。 This usually includes things like can a user create a specific resource with valid data and then do they see errors if they enter invalid data.这通常包括用户是否可以使用有效数据创建特定资源,然后如果他们输入无效数据会看到错误。 A controller test is more for things that a user shouldn't be able to normally do or extreme edge cases that would be too (cu)cumbersome to test with Cucumber. controller 测试更适用于用户无法正常执行的操作,或者使用 Cucumber 测试过于繁琐的极端情况。

Usually when people write controller tests, they are effectively testing the same thing .通常,当人们编写 controller 测试时,他们实际上是在测试同一件事 The only reason to test a controller's method in a controller test are for edge cases.在 controller 测试中测试控制器方法的唯一原因是针对边缘情况。

Edge cases such as if a user enters an invalid ID to a show page they should be shown a 404 page.边缘情况,例如如果用户在显示页面中输入了无效的 ID,他们应该显示 404 页面。 This is a very simple kind of thing to test with a controller test, and I would recommend doing that.这是使用 controller 测试进行测试的一种非常简单的方法,我建议您这样做。 You want to make sure that when they hit the action that they receive a 404 response, boom, simple.你想确保当他们点击动作时,他们会收到 404 响应,繁荣,简单。

Making sure that your new action responds successfully and doesn't syntax error?确保您的new操作成功响应并且没有语法错误? Please.请。 That's what your Cucumber features would tell you.这就是您的 Cucumber 功能会告诉您的。 If the action suddenly develops a Case of the Whoops , your feature will break and then you will fix that.如果该动作突然发展成一个糟糕的案例,您的功能将中断,然后您将修复它。

Another way of thinking about it is do you want to test a specific action responds in a certain way (ie controller tests), or do you care more about that a user can go to that new action and actually go through the whole motions of creating that resource (ie acceptance tests)?另一种思考方式是您是否想测试特定动作以某种方式响应(即 controller 测试),或者您是否更关心用户可以 go 到该new动作并实际上通过创建 Z34D1F91FB2E5714B8576A8 的整个动作 go该资源(即验收测试)?

Maybe not.也许不吧。

Sure you can write tests for your controller.当然,您可以为您的 controller 编写测试。 It might help write better controllers.它可能有助于编写更好的控制器。 But if the logic in your controllers is simple, as it should be, then your controller tests are not where the battle is won.但是,如果您的控制器中的逻辑很简单,那么您的 controller 测试就不是胜利的地方。

Personally I prefer well-tested models and a thorough set of integration (acceptance) tests over controller tests any time.我个人更喜欢经过良好测试的模型和一套完整的集成(验收)测试,而不是 controller 测试。

That said, if you have trouble writing tests for controllers, then by all means do test them .也就是说,如果您在为控制器编写测试时遇到困难那么一定要测试它们 At least until you get the hang of it.至少在你掌握它之前。 Then decide whether you want to continue or not.然后决定是否要继续。 Same goes for every kind of test: try it until you understand it, decide afterwards.每种测试都一样:尝试直到你理解它,然后再决定。

Writing controller tests gives your application permission to lie to you.编写 controller 测试可以让您的应用程序对您撒谎。 Some reasons:一些原因:

  • controller tests are not executed in the environment they are run in. ie they are not at the end of a rack middleware stack, so things like users are not available when using devise (as a single, simple example). controller 测试不在它们运行的环境中执行。即它们不在机架中间件堆栈的末尾,因此在使用 devise 时,用户不可用(作为单个简单示例)。 As Rails moves more to a rack based setup, more rack middlewares are used, and your environment deviates increasingly from the 'unit' behaviour.随着 Rails 更多地转向基于机架的设置,使用了更多机架中间件,并且您的环境越来越偏离“单元”行为。
  • You're not testing the behaviour of your application, you're testing the implementation.您不是在测试应用程序的行为,而是在测试实现。 By mocking and stubbing your way through, you're re-implementing implementation in spec form.通过 mocking 并通过您的方式,您正在以规范形式重新实现实现。 One easy way to tell if you're doing this;一种简单的方法来判断您是否正在这样做; if you don't change the expected behaviour of url response, but do change the implementation of the controller (maybe even map to a different controller), do your tests break?如果您不更改 url 响应的预期行为,但更改 controller 的实现(甚至可能 map 到不同的控制器), If they do, you're testing implementation not behaviour.如果他们这样做了,那么您正在测试实现而不是行为。 You're also setting your self up to be lied to.你也在让自己被骗。 When you stub and mock, there's no assurances that the mocks or stubs you've setup do what you think they do, or even if the methods they're pretending to be exists after refactoring occurs.当您进行存根和模拟时,无法保证您设置的模拟或存根会按照您的想法执行,或者即使它们假装的方法在重构发生后仍然存在。
  • Calling controller methods is impossible via your applications 'public' api.通过您的应用程序“公共”api 调用 controller 方法是不可能的。 The only way to get to a controller is via the stack, and the route.到达 controller 的唯一方法是通过堆栈和路由。 If you can't break it from a request via a url, is it really broken?如果您无法通过 url 将其从请求中中断,那么它真的中断了吗?

I use my tests as an assurance the my application is not going to break when I deploy it.我使用我的测试来保证我的应用程序在部署时不会中断。 Controller tests add nothing to my confidence that my application is indeed functional, and actually their presence decreases my confidence. Controller 测试并没有增加我对我的应用程序确实可以运行的信心,实际上它们的存在降低了我的信心。

One other example, when testing your 'behaviour' of your application, do you care that a particular file template was rendered, or that a certain exception was raised, or instead is the behaviour of your application to return some stuff to the client with a particular status code?另一个例子,当测试你的应用程序的“行为”时,你是否关心呈现了特定的文件模板,或者引发了某个异常,或者你的应用程序的行为是否将一些东西返回给客户端特定的状态码?

Testing controllers (or views) increases the burden of tests that you impose on yourself, and means that the cost of refactoring is higher than it needs to be because of the potential to break tests.测试控制器(或视图)会增加您对自己施加的测试负担,这意味着重构的成本高于所需的成本,因为可能会破坏测试。

Should you test?你应该测试吗? yes是的

There are gems that make testing controllers faster有些宝石可以让测试控制器更快

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

Definitely test the controller.绝对测试 controller。 A few painfully learned rules of thumb:一些痛苦的经验法则:

  • mock out model objects模拟 model 对象
  • stub model object methods that your controller action uses您的 controller 操作使用的存根 model object 方法
  • sacrifice lots of chickens.牺牲很多鸡。

I like to have a test on every controller method at least just to eliminate stupid syntax errors that may cause the page to blow up.我喜欢对每个 controller 方法进行测试,至少只是为了消除可能导致页面崩溃的愚蠢语法错误。

A lot of people seem to be moving towards the approach of using Cucumber for integration testing in place of writing controller and routing tests.很多人似乎正在转向使用 Cucumber 进行集成测试来代替编写 controller 和路由测试的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我应该如何使用rspec测试路由和控制器? - How should I test routes and controllers with rspec? Rspec:一次测试中如何有多个控制器? 如何在测试中更改控制器? - Rspec: How can I have many controllers in one test? How can I change controllers in a test? 我真的应该为此使用观察者吗,因为Ruby Guides要求我考虑 - Should I really be using an observer for this as Ruby Guides asks me to consider 我应该在哪里将供多个控制器使用的方法放在rails中? - Where should I put methods to be used by multiple controllers in rails? 在这种情况下,我应该创建多少个控制器以遵循“轨道方式”? - How many controllers should I create in this situation to stick to the “Rails Way”? 我应该在一个控制器中创建多个控制器还是多个更新方法? - Should I be creating multiple controllers or multiple update methods in one controller? 如何在Rails的多个控制器中渲染对象? - How should I render an object in multiple controllers in Rails? Rails:我应该如何在控制器之间共享逻辑? - Rails: how should I share logic between controllers? 我应该在哪里获取推文? (控制器,模型,助手等) - Where exactly should I fetch tweets? (controllers, models, helpers, …) 我应该把我自己的不是模型/视图/控制器的类放在哪里? - Where should I put my own classes that are not models/views/controllers?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM