While rspec automatically creates specs for any helpers created by the Rails generators, I was wondering if other Rails developers find it important/useful to spec the helpers in real-world or if they often don't bother, since the helpers are often tested by proxy through testing of the components that use them?
Personally I do test helper methods, because I like to test them in isolation. If the following feature specs fails I know I probably made a mistake in my test setup because I already ensured that the helper method works.
It is also easier to test all possible scenarios. If you want to test all possibilities as part of a whole you need more test setup and sacrifice performance.
Ideally, you want to write tests for everything, but in real world with time constraints, it is not uncommon to skip simple helper method tests because you implicitly test them while building the actual test. In the same way some developers may skip private method tests.
Related
I'm digging into Capybara and rspec, to move from TDD to BDD.
My generators make a whole lot of directories and spec tests,
with directory structure similar to this:
spec
controllers
models
requests
routing
views
I think that most of this is TDD rather than BDD. If I read here:
"A great testing strategy is to extensively cover the data layer with
unit tests then skip all the way up to acceptance tests. This approach
gives great code coverage and builds a test suite that can flex with a
changing codebase."
Then I figure that things should be quite different
something on the lines of:
spec
models
acceptance
Basically I take out controllers, requests, views, and routing to just implement tests as user case scenarios in the acceptance directory with Capybara, Rspec.
This makes sense to me, though I'm not sure if this is the standard/common approach to this.
What is your approach?
Thanks,
Giulio
tl;dr
This is not a standard approach.
If you only test models and feature specs... then you miss out on the bits in the middle.
You can tell: "method X broke on the Widget model" or you can tell "there's something wrong while creating widgets" but you have no knowledge of anything else.
If something broke, was it the controller? the routing? some hand-over between the two?
it's good to have:
extremely thorough testing at the model-level (eg check every validation, every method, every option based on incoming arguments)
rough testing in the middle to make sure sub-systems work the way you expect (eg controllers set up the right variables and call the right templates/redirections given a certain set of circumstances)
overall feature testing as smoke-tests (eg that a user can go through the happy path and everything works the way they expect... that if they input bad stuff, that the app is throwing up the right error messages and redisplaying the forms for them to fix the problem)
Don't forget that models aren't the only classes in your app.. and all classes need some kind of testing. Controllers are classes too. As are form and service objects, mailers, etc.
That said - it's common to consider that view-tests are going overboard. I'm also not keen on request-tests our routing test myself (unless I have something complex which I want to work right, eg lots of optional params in a route that map to interesting search-patterns)
Rspec noob here, just trying to improve my test coverage.
One very basic yet important question I have is just: What kinds of tests go where?
Model tests are straight forward. I just need to test the functionality of the models methods and validations. View tests seem simple. That would just be testing that each view renders the desired data.
What confuses me is what exactly goes in my Request Specs. Most of my rails experience is from following Michael Hartle's Rails Tutorial. His Request specs seem to be based around a series of actions that the user could take in the application. But he also includes test which seem like they should be in the View Specs that I am considering moving elsewhere.
If someone could help me understand what kinds of tests go in Request, that would be helpful.
From the RSpec docs:
Request specs provide a thin wrapper around Rails' integration tests, and are
designed to drive behavior through the full stack, including routing
(provided by Rails) and without stubbing (that's up to you).
With request specs, you can:
specify a single request
specify multiple requests across multiple controllers
specify multiple requests across multiple sessions
Check the rails documentation on integration tests for more information.
From Rails' docs on integration tests:
Integration tests are used to test the interaction among any number of controllers. They are generally used to test important work flows within your application.
If your test has to do with how a single view is rendered (which should be completely decoupled from any actual HTTP request), then it's probably better as a view test. If it has to do with multiple views or multiple requests, then an integration test is probably more appropriate.
In the past couple of days I've been making slow progress adding tests to an existing rails app I've been working on for a little bit.
I'm just trying to figure out how much and what kind of tests (unit, functional, integration) will be enough to save me time debugging and fixing deploys that break existing functionality.
I'm the only one working on this application. It's basically an inventory management database for a small company (~20 employees). I didn't add testing from the beginning because I didn't really see the point but I've have a couple of deploys screw up existing functionality in the last little bit, so I thought it might be a good thing to add.
Do I need to test my models and controllers individually AND perform integration testing? There seem to be developers who believe that you should just integration test and backtrack to figure out what's wrong if you get an error from there.
So far I'm using RSpec + Factory Girl + Shoulda. That made it pretty easy to set up tests for the models.
I'm starting on the controllers now and am more than a little bit lost. I know how to test an individual controller but I don't know if I should just be testing application flow using integration tests as that would test the controllers at the same time.
I use integration tests to test the successful paths and general failure paths, but for the edge cases or more in-depth scenarios then I write model/view/controller tests.
I usually write the tests before writing the functionality in the application but if you want to add tests afterwards then I recommend using something like SimpleCov to see which areas of your application need more testing and slowly build up the test coverage for your application.
Writing tests after the app is already written is going to be tedious. At a minimum you should be testing for integration cases (which will test most controller functions and views), and also model tests separately so that your model calls work as you think they should.
For integration testing I find Capybara easy to use.
As a rule of thumb, most of your tests need to be unit, some functional, few integration.
Rails adheres to this wholeheartedly and you should do the same.
At the minimum you have to have:
A unit test for each of your models, add a test case for each of your validations in each of them, and finally a last one to make the sure the model is saved. If you have stuff like dependant: :destroy, touch: true on related models (has_many, belongs_to), add test cases for them as well.
A functional test for each of your controllers. Test cases for each action. Some actions can have multiple responses (like in case of 422 errors) so add another case to test the error response. If you have a authorization filter, test them as well.
Then you can have an integration test for a typical new user flow. Like
Sign Up -> Create Post -> View it -> logout. Another one is to make sure that unauthorized users cannot access your resources.
And from now, do not commit ANY code without the above mentioned tests.
The best time to plant a tree was 10 years ago, second best time is now, so start testing!
When scaffolding controllers it will create tests for that model, do the test have the ability to check for runtime errors for the whole page including rendering the .erb
If so can tests scan for common typos in the .erb for example checkbox instead of check_box
Because silly typos take a stupid amounts of time to figure out because the code looks right.
It would be good if there was a plugin that would use a service to check if it's a common typo or gotcha.
In general I test the controller in the controller tests and the views in the view tests.
In more detail, I will test that given the right input to the controller, it produces the right output. I usually mock out the model(s) involved and concentrate on what work matters inside the controller. In my view tests I simply validate that the things on the page look like what I want them to look. I also use Jasmine to test javascript when I have more complex interactions in that body of code.
I put a lot of stock in this separation of tests.
I use rspec for my model, view, controller, routing and request tests and I write failing tests and then implement the feature/method to make those tests go green. And also I run rake spec before checking in. This gives me good coverage on the type of things you're concerned about.
There is also a gem called autotest that will run a test each time you save them (or perhaps some other granularity). If your test is green it will run the entire suite. I don't use it because I don't like how aggressively it does this but I have friends that swear by it.
I use RSpec to test my lovely little web app. For integration tests I use Steak. When using Rails generators (yep, I know that this is not the Zen way of doing TDD) there are also some files in spec/requests generated. As stated on link text it is something similiar to integration test (but I couldn't find much more info).
Are those request specs still recommended when using something like Steak and Cucumber?
It all depends on what you need and want. The goal of testing is to prove that your app works once, not twice or more times.
I personally write rspec tests for models and helpers. I use cucumber to test that my views and controllers are working the way I expect them to. With this I can prove that my entire app works as I expect it to, so no, I don't use spec/requests.
Occasionally I do use spec/requests to test APIs, but you can do that with cucumber as well.
Some don't like the BDD-way cucumber works and stick with spec/requests. In the end it's all a matter of taste.