Is there a cucumber hook to run before and after each feature

前端 未结 6 750
后悔当初
后悔当初 2020-12-10 04:39

Is there a way to run specific code block before and after each cucumber feature with certain tag?

Since setup process is very expensive I don\'t want to run it bef

相关标签:
6条回答
  • 2020-12-10 04:59

    Few days ago I've spoke with Matt Wynne (one of the core team member of cucumber gem) and he told me that there is no such feature in cucumber (at the time of writing this).

    As a workaround he suggested to tag whole feature and use before each hook with a flag like so:

    Before('@feature_with_expensive_setup') do
      unless @setup_is_done
        # perform expensive setup code here ..
        @setup_is_done = true
      end
    end
    
    0 讨论(0)
  • 2020-12-10 05:03

    The hooks for cucumber are described in this wiki page which show the before and after hooks you can have.

    Taken from that page is this example:

    The following example will cause scenarios tagged with @fast to fail if the execution takes longer than 0.5 seconds:

    Around('@fast') do |scenario, block|
      Timeout.timeout(0.5) do
        block.call
      end
    end
    
    0 讨论(0)
  • 2020-12-10 05:05

    a modification of the first answer works for me with single quotes

        Before('@feature_with_expensive_setup') do
          unless '@setup_is_done'
            # perform expensive setup code here ..
            @setup_is_done = true
          end
        end
    
    0 讨论(0)
  • 2020-12-10 05:20

    LukasMac's answer didn't work with @ variable. Ande based on official cucumber wiki page, my example below worked and tested ok, the before hook below only execute once per feature:

    Before('@my_feature_tag') do
      unless $dts_test_preparation_done
        # expensive setup in my case setup lots of database tables for test
        $dts_test_preparation_done = true
      end
    end
    
    0 讨论(0)
  • 2020-12-10 05:21

    Cucumber before and after feature hooks

    Usage info

    As ruby cucumber does not come supplied with the option to create hooks for before and after a feature, an ad hoc solution has been put forward.

    In order to specify a hook relating to a feature, the method name must be in the following format:

    before_feature_[formatted feature name] after_feature_[formatted feature name]

    Where the formatted feature name is the text from the 'Feature:' line in the feature file formatted with:

    (i) all characters lowercased; (ii) all spaces replaced with underscores; and, (iii) all special characters deleted

    Within methods matching this convention code can be specified as with scenario hooks.

    Technical info

    Building on the solutions by LukasMac and Gob00st I have implemented the following workarounds for my current client.

    The methods go in a hooks subdirectory called AAA_special_hooks, in a special_hooks.rb file in that directory (the sole file), this is because all other things being equal the hooks will be run in the order they appear in the project structure and this way the hooks created here are run before any scenario hooks specified in other subdirectories or in the hooks base directory.

    The code in the below appendix is vanilla, so far as I can see it would work for anyone.

    The before hook runs on the principle of setting a global flag to ensure the hook is only run once for a feature (as per LukasMac and Gob00st). That principle has been extended to the abstract hook for two reasons, firstly to simplify the specification of hooks in general and also to have consistency with the after hook implementation.

    The after hook is designed to determine whether the feature has changed since the last scenario was executed. If so the after hook will be run for the previous feature before anything happens in the current one. Clearly the vulnerability could be that the new feature has in fact been started before the after hook runs for the previous one, but I can't see how this might cause any issues. The final feature however cannot have an after hook run in this way and that is the reason for the reimplementation of that code in the at_exit method.

    Appendix - special_hooks.rb code

    def get_formatted_name(feature_name)
      formatted_name = feature_name.downcase.gsub(' ', '_')
      %w[@ ' , . / ! " £ $ % ^ & * ( ) { } [ ] ; : # ~ ? < > \] + = - ` ¬ |].each { |char| formatted_name.gsub! char, '' }
      formatted_name
    end
    
    Before do |scenario|
      $completed_before_hooks ||= []
      $feature_name ||= scenario.feature.name
      unless $feature_name == scenario.feature.name
        # run after hook for previous feature
        begin
          send "after_feature_#{get_formatted_name $feature_name}"
        rescue NoMethodError
        end
      end
    
      #run before hook for current feature if not already done
      begin
        formatted_name = get_formatted_name scenario.feature.name
        unless $completed_before_hooks.include? formatted_name
          $completed_before_hooks << formatted_name
          send "before_feature_#{formatted_name}"
        end
      rescue NoMethodError
      end
    
      $feature_name = scenario.feature.name
    end
    
    at_exit do
      # don't run final hook if error raised that was not handled
      unless $! && $!.status > 1
        puts 'EXECUTING FINAL AFTER HOOK... PLEASE WAIT'
        begin
          send "after_feature_#{get_formatted_name $feature_name}"
        rescue NoMethodError
        end
        puts 'FINAL AFTER HOOK COMPLETED'
      end
    end
    
    0 讨论(0)
  • 2020-12-10 05:25

    Mocking of BeforeFeature/ AfterFeature hooks is achievable by tagging the first scenario of the feature with a tag say @ExecuteBeforeFeature and last scenario with tag say @ExecuteAfterFeature and then writing the tagged Before and After hooks as following:

    Before('@ExecuteBeforeFeature') do
      #code in this method will be executed only before the first scenario or before the feature if only the first scenario is tagged for this hook.
    end
    
    After('@ExecuteAfterFeature') do
      #code in this method will be executed only after the last scenario or after the feature if only the last scenario is tagged for this hook.
    end
    
    0 讨论(0)
提交回复
热议问题