Today I re-learned a valuable lesson about making a test fail before letting it
pass. I was working on an old codebase that wasn’t using the
site prism gem and so I was doing
some DOM checking by hand in Cucumber, something
I hadn’t done in a while. In a step definition I expected that if I returned
false
, the step would fail. This, however, is not the case!
I feel like I have known this for a long time but simply forgot. The rest of the steps that check things use rspec to do so with syntax like:
1
|
|
But I didn’t remember or notice that at first. Here’s the step definition I thought would fail properly, and fail at the correct line, giving a “good error message” to boot.
1 2 3 4 5 6 |
|
It passed the first time and I almost moved on, but I decided to change the default value for the last table cell and make sure it falied. In this app the UI shows a default value of “TBD” if a user logs in to check their application status and that field isn’t yet populated. Thank goodness I checked because it continued to pass. And then I couldn’t for the life of me make it fail!
1 2 3 |
|
passed…
1 2 3 |
|
passed…
I was getting very concerned. If I issued a raise statement it would error out… so why weren’t my checks that evaluated to false causing cucumber to fail?!?!
As it turns out, it doesn’t matter what you return in a step definition. You have to raise an error if you want the step to fail. I must have never fully groked that since I previously always remembered to just use rspec when evaluating outcomes in a step definition.
So after 10 minutes of wondering if I was going to be filing a bug against cucumber, I finally ended up with this step def failing properly:
1 2 3 4 5 6 7 8 9 |
|
After changing one of the table columns to have the text ‘FOO’ instead of ‘TBD’ the failures generated out of this step definition now work, but it’s not a very obvious failure. Something that, again, I wouldn’t have noticed if I haden’t taken the time to watch the test fail.
1 2 3 4 5 6 7 8 |
|
The problem here is that the line rspec points out is the final line that actually does the assertion. This doesn’t help us track down which css class has the incorrect text.
So the final refactored version, while somewhat less DRY, is actually a net win when the failure crops up 6 months down the road. The failure message tells me exactly what css class has the text not matching my expectation.
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 8 |
|
This makes it very clear that line 5 is the offending line, and I can go check
td.revenue
to see what’s up.