Are you satisfied with your tests?
The best talk I saw at CodeMash 2.0.1.1 was Jim Weirich‘s on Are you satisfied with your tests?. It likely could have been a keynote, or at least in a bigger room than it was in (to considerable whinging on Twitter). And for all the overcrowding (people in the hall listening, sitting on the floor at the front of the room, etc.), there were only three women in the audience. Not sure what that last data point means, but Greg as inadvertently trained me to notice these things.
Before I get to the notes; two things.
- The talk really should be ‘Are you satisfied with your checks‘ — what you name something is important
- I could also understand the ‘coolness’ that RSpec allows. Clearly my introduction to it was an abominable example of it.
And now the notes, starting with the ‘patterns’(?)
- (Bad) Slow tests
- Jeff Nielsen did a talk a number of years ago at Agile on the Psychology of build times
- The magic appears to be unit tests
- Never heard of the split between unit and checkin tests. Interesting.
- (Bad) Blase attitude towards failing tests
- (Bad) Over Mocking
- When to mock
- Using an external service
- Verifying a protocol
- Smells
- Mocks that return mocks
- Fantasy tests (fail when the code is good and pass when the code is bad)
- When to mock
- (Bad) Complex object builds
- Use factories — but be aware of how your factory works
- (Bad) Gratuitous use of the database
- In [rails] tests
- s/create/new
- s/save/valid?
- In [rails] tests
- Bad – Over meta in tests
- Do not go meta unless it really buys you something
- Bad – Testing private methods
- Pathological coupling often is required
- Every time you test a private method….
- (Bad) Incorrect use of describe / context (RSpec keywords)
- describe and context are synonyms
- describe is for a noun, a thing
- context is the situations (when…, with…)
- (Good) Custom assertions
- Makes your tests readable and understandable
- (Good) Refactoring tests
- Tests are code, which means they need refactoring as well
- Oh, and know your framework (subject, before, etc.)
- rspec-given gem bring Given, When, Then semantics to RSpec
- (Good) Specifications (not tests)
- Testing code -> specifying behaviour
- RSpec != specifying behaviour
Which lead to how we should write specifications
- Necessary
- Sufficient
- (Important) Public methods
- Names
- Arguments
- Contract
- (Important) Public protocols
- (Not Important) Private methods
- (Not Important) Ancillary objects
And finally, two heuristics
- Test things that can break
- If you don;t think you need to test it, then don’t. And when things break you know you are being too lax