While enjoying the facets of Ruby and BDD with cucumber, you might come across a puzzling issue. Cucumber offers hooks for various events during testing, such as hooking before a scenario is run, after a scenario, and providing room for designs of your own fancy before & after your test’s execution by capturing a tag with the ‘Around’ syntax, for example. All of these hooks are helpful, but there’s a quirk with hooking after a scenario which may leave you wondering if your hook was even executed at all.
The syntax for an after hook in Ruby looks like this:
After do |scenario|
puts “scenario ended”
After adding similar code to your ruby steps, you may notice that of your 10 finished scenarios, you only count 9 “scenario ended” prints. If you only run one scenario, you’ll notice your string isn’t printed at all. Cucumber does some interesting work behind the scenes with regard to ‘puts’.
When you run any scenario, cucumber is very kind in placing your step definition output immediately following the feature’s step. Inlining these prints comes at a cost: to do this, cucumber replaces the default implementation of ‘puts’ with a buffered approach. Calls to ‘puts’ during your cucumber tests will actually write your strings to a cucumber buffer, which is then flushed at the appropriate time: after a scenario step, at the end of a scenario, etc. The exception is after the last scenario step, the ‘puts’ buffer is not flushed, and your strings will never see the light of day. A simple workaround?
STDOUT.puts “hello world”
Directly calling ‘puts’ on the standard stream will not use cucumber’s buffered implementation, and accordingly, STDERR.puts works as well. Next time you wonder where your strings went, try to remember where you “puts” them.