### If you need to access a remote service in any way
``` ruby
group :cucumber do
gem 'webmock', '~> 1.8.0', :require => nil
gem 'vcr', :require => nil
end
```
### What everything does
Some of my custom gems are pretty cowboyed up, but they work for me, so YMMV.
#### `semantic_rails_view_helpers`
[This gem](http://github.com/johnbintz/semantic_rails_view_helpers) provides view helpers and Capybara finders that, when used with a form builder gem like Formtastic, allow for
very fast form & show construction, and makes it easy to write tests to target elements on those views.
#### `cuke-pack`
[This gem](http://github.com/johnbintz/cuke-pack) helps you set up a lot of common Cucumber environment settings, like support for Timecop, FakeFS, and Mocha;
helps with confirming JavaScript dialogs; enables `cucumber-step_writer`; sets up Guard for a work-in-process workflow; provides a one-at-a-time failed test rerun feature.
[Exactly what it sounds like](http://github.com/johnbintz/cucumber-step_writer). Writes out your missing Cucumber steps into `features/steps/(given|when|then)` so you don't
have to copy-paste them anymore.
#### `foreman` and `guard`
For testing, starting both Guard and persistent_selenium is made easy with Foreman. During development, if you have any
dependent services like a Delayed Job worker or API tunnel, Foreman makes it a lot easier to work with.
[Keep a Firefox or Chrome window open](http://github.com/johnbintz/persistent_selenium) while you test, and don't close or reset the page after a failed step. Very helpful
in quickly diagnosing problems and fixing them. Occasional DRb errors, but that's on about one of ever 100 runs or so.
Normally, errors go in your `log/test.log`. [This](http://github.com/johnbintz/capybara-rails-log-inspection) redirects them to `$stderr`, so you can see exceptions in your Guard
When running a standard Cucumber run (using the `default` profile) or a `precommit` run, if you are using the cuke-pack
`in_progress` hook and there are test failures, you'll get an `in_progress.txt` file in your project root. This
file works very much like Cucumber `rerun.txt` style of testing, except instead of running all features at once (`@rerun.txt`'s
normal behavior), it runs them one at a time until each one passes, eliminating the passing one from the list as you go.
Internally, this uses `@rerun.txt` within a now-smart Cucumber profile, but it only passes in one feature at a time. There's
no need to use `@wip` tags for this either. It will run and eliminate passing scenarios until everything in the `in_progress.txt`
list is fixed. This takes over `@wip` tag processing, and will let you use `@wip` tags again once the list is empty or you
delete `in_progress.txt`.
For now, to make this work with Guard, use [my fork's `paths_from_profile` branch](https://github.com/johnbintz/guard-cucumber/tree/paths_from_profile) of `guard-cucumber`. Once this gets some more human
testing, I'll submit it as a pull request against `guard-cucumber`.
Rails gives you a lot of built-in tools to keep you from writing a lot of code. But there are gems out there that
let you get away with writing even less code, which means you have less things to test. You should never "test the
framework" when you write tests -- assume that the author of the tools you use have tested them thoroughly, unless
otherwise discovered (and then help the author by pinpointing the problem and sending code to fix it!) That's
why I'm not a fan of things like model validation tests: the model file clearly says `validates :something`, there's
no need to test that directly, unless you think Rails itself is broken. Indirect testing through integration
testing is fine, though (but probably mostly unnecessary).
For a "typical" Rails application which provides some sort of HTML-based interface to end users, I'll use
most of, of not all of, the following gems:
* [inherited_resources](http://github.com/josevalim/inherited_resources): Rails controller generators are OK, but this
is way faster. With this, you don't even have to feel guilty about not having controller unit tests that are
essentially "I have set an instance variable and called the render method".
* [formtastic](http://github.com/justinfrench/formtastic): Writing forms is lame. Formtastic lets you do it a lot
faster, makes it easier to target your form elements using Capybara and semantic_rails_view_helpers, and
makes writing custom form elements a snap, even ones that have JavaScript in them.
* [draper](http://github.com/drapergem/draper): Views shouldn't have any more logic than the occasional `if` statement.
Put the rest of that logic in decorators. Combine that with [decorates_before_rendering](http://github.com/ohwillie/decorates_before_rendering)
for stupid-simple decorators.
* [Active Admin](http://github.com/gregbell/active_admin): If you don't need to write an admin interface, don't do it.
* [cocoon](http://github.com/nathanvda/cocoon) and [my fork](http://github.com/johnbintz/cocoon): `accepts_nested_attributes_for` get some well-deserved hate, but
if you truly are only putting nested attributes into an object in a single way, and you're doing it with a gem like cocoon, then it's perfectly acceptable IMHO.
Write a Form Object to accept the input if you really care that much about that sort of thing.
* [virtus](http://github.com/solnic/virtus): For things like View Objects and Value Objects and Form Objects, make those objects behave like
ActiveRecord objects. (Read [this article](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) for some background on that.)
For something that's more of a "service", I'll still use what tools I can, but the test flow may be different.
Of course, you'll have your authentication gems and your asset-related gems and your pagination gems, but those
aren't about writing less code or better organized code.
## Thing will go wrong and my code will fail. Get over it.
I fully expect that I will make mistakes during development, either through incorrect assumptions or just plain shoddy work.
I'm getting better at programming, but I'm not perfect. I use, at the very least, [exception_notification](https://github.com/smartinez87/exception_notification)
to catch problems. If I have access to Errbit or Airbrake or something similar for catching and reporting exceptions, I'll use it. When it breaks,
if my actual code is clean enough, it should be easy to create a new feature, or fix a bad one, and get the problem resolved.