Writing Good Test Descriptions
Anyone can write a decent test description. But by paying attention to this little detail you can write great test descriptions:
Block descriptions should start with a word that forms a readable sentence in conjunction with the block function name.
But what does this really mean in practice? Let’s find out.
describe defines the subject under test:
describe 'Watch' do # ... end
Here we are testing the
describe should be followed by the class, function or object that we want to test.
it lays out the test case — the behaviour and outcome we expect. But linguistically,
it refers to the actual thing we are testing:
describe 'Watch' do it 'should tell the time' do # ... end end
We are meant to read the test description as if it were a sentence.
It should tell the time.
The watch should tell the time.
That is why
it should be followed by the words “should” or “must”.
An alternative is to write test descriptions in the present tense:
describe 'Watch' do it 'tells the time' do # ... end end
This still works as a sentence:
It tells the time.
The watch tells the time.
context groups tests that are made under the same circumstances:
describe 'Watch' do context 'when under water' do before do placeWatchUnderWater() # setup common to all tests inside this context end it 'should still tell the time' do # it's a diver's watch! # ... end it 'should measure depth' do # ... end end end
Once again we are meant to read the test description as if it were a sentence.
When under water, it should still tell the time.
The watch, when under water, should still tell the time.
That is why
context should be followed by the words “when”, “with”, “without” or “if”.
By adopting this simple guideline you can make your test descriptions easier to read and comprehend.
An added bonus is that many testing frameworks can be configured to output their results in a BDD format.
For example, using rspec’s format option, when all the tests pass:
$ rspec -fd watch.rb Watch should tell the time when under water should still tell the time should measure depth Finished in 0.00237 seconds 3 examples, 0 failures
And when some tests fail:
$ rspec -fd watch.rb Watch should tell the time when under water should still tell the time (FAILED - 1) should measure depth (FAILED - 2) Failures: 1) Watch when under water should still tell the time Failure/Error: expect(watch.time).to eq '12:00' expected: "12:00" got: "0" (compared using ==) 2) Watch when under water should measure depth Failure/Error: expect(watch.depth).to eq 10 expected: 10 got: 0 (compared using ==) Finished in 0.02115 seconds 3 examples, 2 failures Failed examples: rspec ./watch.rb:22 # Watch when under water should still tell the time rspec ./watch.rb:26 # Watch when under water should measure depth
Notice how the test descriptions can be read as full sentences. We can immediately tell what went wrong.
It’s not a diver’s watch after all!