After writing tests with a lot of different pairs, hacking on a lot of existing tests, and reading various blog posts, I've settled on a set of RSpec practices which work well for me:
- Keep "it" blocks as small as practical. Strive for one assertion each.
- Invert dependencies as if your life depends on it.
- Nested describe blocks are your friends.
- Using "context" is sometimes more descriptive than "describe."
- A describe block for each method annoys the crap out of some people, but works well for me. Try it and let me know what you think.
- Don't retest behavior which is already verified in another nearby test.
- There's a matcher for that.
- Go ahead and say "test" instead of "spec" if you feel like it. The world won't end.
- Mercilessly refactor your tests for clarity, especially by extracting methods.
- Testing small pieces makes test-first easier.
- Brevity is the essence of wit.
- "let" will make your life easier, but not always.
- Don't fear mocks or stubs. If mocking/stubbing becomes hard, that's a code smell.
- If your tests are ugly, consider how changing the design of your code might make the tests cleaner. This almost always yields better code.
- In particular, your tests may tell you when it's time to split a class in two.
- Rails test fixtures will get you into trouble.
- The "pending" feature is a thing of beauty. It helps test-first to play nicely with CI.
- Stop guessing. Take a little time to learn ruby-debug, Pry, or something comparable.
- Prefer logging to puts when debugging.
- Writing custom matchers isn't so bad.
- Require individual classes as needed in your spec files rather than requiring everything in spec_helper.
- Order-dependent test failures? Look for global state and crush it like a bug.
- Use Guard. It's easy to set up and saves you time.
- Stub out external services with realweb or rack-client.
- Prefer options in .rspec to explicit configuration in your spec helper—other developers might not like the same options as you.
- -cfs works well for me.
- Explicit use of "subject" makes your tests less readable.