Feature: Around hooks In order to support transactional scenarios for database libraries that provide only a block syntax for transactions, Cucumber should permit definition of Around hooks. Background: Given a file named "features/support/env.rb" with: """ module HookLoggerWorld def logged_hooks @logged_hooks ||= [] end def log_hook(name) logged_hooks << name end end World(HookLoggerWorld) """ Scenario: A single Around hook Given a file named "features/step_definitions/steps.rb" with: """ Then /^the hook is called$/ do expect(logged_hooks).to eq(['Around']) end """ And a file named "features/support/hooks.rb" with: """ Around do |scenario, block| log_hook('Around') block.call end """ And a file named "features/f.feature" with: """ Feature: Around hooks Scenario: using hook Then the hook is called """ When I run `cucumber features/f.feature` Then it should pass with: """ Feature: Around hooks Scenario: using hook # features/f.feature:2 Then the hook is called # features/step_definitions/steps.rb:1 1 scenario (1 passed) 1 step (1 passed) """ Scenario: Multiple Around hooks Given a file named "features/step_definitions/steps.rb" with: """ Then /^the hooks are called in the correct order$/ do expect(logged_hooks).to eq(['A', 'B', 'C']) end """ And a file named "features/support/hooks.rb" with: """ Around do |scenario, block| log_hook('A') block.call end Around do |scenario, block| log_hook('B') block.call end Around do |scenario, block| log_hook('C') block.call end """ And a file named "features/f.feature" with: """ Feature: Around hooks Scenario: using multiple hooks Then the hooks are called in the correct order """ When I run `cucumber features/f.feature` Then it should pass with: """ Feature: Around hooks Scenario: using multiple hooks # features/f.feature:2 Then the hooks are called in the correct order # features/step_definitions/steps.rb:1 1 scenario (1 passed) 1 step (1 passed) """ Scenario: Mixing Around, Before, and After hooks Given a file named "features/step_definitions/steps.rb" with: """ Then /^the Around hook is called around Before and After hooks$/ do expect(logged_hooks).to eq(['Around', 'Before']) end """ And a file named "features/support/hooks.rb" with: """ Around do |scenario, block| log_hook 'Around' block.call log_hook 'Around' expect(logged_hooks).to eq(['Around', 'Before', 'After', 'Around']) end Before do |scenario| log_hook 'Before' end After do |scenario| log_hook 'After' expect(logged_hooks).to eq(['Around', 'Before', 'After']) end """ And a file named "features/f.feature" with: """ Feature: Around hooks Scenario: Mixing Around, Before, and After hooks Then the Around hook is called around Before and After hooks """ When I run `cucumber features/f.feature` Then it should pass with: """ Feature: Around hooks Scenario: Mixing Around, Before, and After hooks # features/f.feature:2 Then the Around hook is called around Before and After hooks # features/step_definitions/steps.rb:1 1 scenario (1 passed) 1 step (1 passed) """ Scenario: Around hooks with tags Given a file named "features/step_definitions/steps.rb" with: """ Then /^the Around hooks with matching tags are called$/ do expect(logged_hooks).to eq(['one', 'one or two']) end """ And a file named "features/support/hooks.rb" with: """ Around('@one') do |scenario, block| log_hook('one') block.call end Around('@one or @two') do |scenario, block| log_hook('one or two') block.call end Around('@one and @two') do |scenario, block| log_hook('one and two') block.call end Around('@two') do |scenario, block| log_hook('two') block.call end """ And a file named "features/f.feature" with: """ Feature: Around hooks @one Scenario: Around hooks with tags Then the Around hooks with matching tags are called """ When I run `cucumber -q -t @one features/f.feature` Then it should pass with: """ Feature: Around hooks @one Scenario: Around hooks with tags Then the Around hooks with matching tags are called 1 scenario (1 passed) 1 step (1 passed) """ Scenario: Around hooks with scenario outlines Given a file named "features/step_definitions/steps.rb" with: """ Then /^the hook is called$/ do expect(logged_hooks).to eq(['Around']) end """ And a file named "features/support/hooks.rb" with: """ Around do |scenario, block| log_hook('Around') block.call end """ And a file named "features/f.feature" with: """ Feature: Around hooks with scenario outlines Scenario Outline: using hook Then the hook is called Examples: | Number | | one | | two | """ When I run `cucumber features/f.feature` Then it should pass with: """ Feature: Around hooks with scenario outlines Scenario Outline: using hook # features/f.feature:2 Then the hook is called # features/f.feature:3 Examples: | Number | | one | | two | 2 scenarios (2 passed) 2 steps (2 passed) """ Scenario: Around Hooks and the Custom World Given a file named "features/step_definitions/steps.rb" with: """ Then /^the world should be available in the hook$/ do $previous_world = self expect($hook_world).to eq(self) end Then /^what$/ do expect($hook_world).not_to eq($previous_world) end """ And a file named "features/support/hooks.rb" with: """ Around do |scenario, block| $hook_world = self block.call end """ And a file named "features/f.feature" with: """ Feature: Around hooks Scenario: using hook Then the world should be available in the hook Scenario: using the same hook Then what """ When I run `cucumber features/f.feature` Then it should pass