簡體   English   中英

在每個功能之前和之后是否有一個黃瓜鈎可以運行

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

有沒有辦法在每個帶有特定標簽的黃瓜特征之前和之后運行特定的代碼塊?

由於設置過程非常昂貴,我不想在每個場景之前運行它。

幾天前,我與Matt Wynne(黃瓜寶石的核心團隊成員之一)進行過交談,他告訴我黃瓜沒有這樣的特征(在撰寫本文時)。

作為一種解決方法,他建議在每個鈎子之前標記整個特征和使用標志,如下所示:

Before('@feature_with_expensive_setup') do
  unless @setup_is_done
    # perform expensive setup code here ..
    @setup_is_done = true
  end
end

LukasMac的答案與@var不兼容。 Ande基於官方的黃瓜維基頁面,下面我的例子工作和測試好了,下面的掛鈎只執行一次每個功能:

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

特色掛鈎之前和之后的黃瓜

使用信息

由於紅寶石黃瓜沒有提供在特征之前和之后創建鈎子的選項,因此提出了一種臨時解決方案。

要指定與要素相關的掛鈎,方法名稱必須采用以下格式:

before_feature_ [格式化功能名稱] after_feature_ [格式化功能名稱]

格式化的要素名稱是特征文件中“要素:”行中的文本,其格式為:

(i)所有字符小寫; (ii)所有空格均以下划線代替; (iii)刪除所有特殊字符

在匹配此約定的方法中,可以使用場景掛鈎指定代碼。

技術信息

在LukasMac和Gob00st的解決方案的基礎上,我為我當前的客戶實施了以下變通方法。

這些方法在一個名為AAA_special_hooks的hooks子目錄中,位於該目錄(唯一文件)中的special_hooks.rb文件中,這是因為所有其他條件相同,鈎子將按照它們在項目結構中出現的順序運行,這樣此處創建的掛鈎在其他子目錄或掛鈎基目錄中指定的任何方案掛鈎之前運行。

下面附錄中的代碼是vanilla,據我所知它可以適用於所有人。

before鈎子的運行原則是設置一個全局標志,以確保鈎子只為一個特征運行一次(根據LukasMac和Gob00st)。 由於兩個原因,該原則已經擴展到抽象鈎子,首先是簡化鈎子的規范,並且與后鈎子實現具有一致性。

掛鈎用於確定自上次方案執行以來功能是否已更改。 如果是這樣,在當前特征發生任何事件之前,將對前一特征運行后鈎子。 顯然,該漏洞可能是新功能實際上已經在之前的掛鈎運行之前啟動,但我無法看到這可能會導致任何問題。 但是最終的特性不能以這種方式運行后鈎子,這就是在at_exit方法中重新實現該代碼的原因。

附錄 - special_hooks.rb代碼

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.5秒,以下示例將導致使用@fast標記的方案失敗:

Around('@fast') do |scenario, block|
  Timeout.timeout(0.5) do
    block.call
  end
end

可以通過使用標記@ExecuteBeforeFeature標記特征的第一個場景以及標記為@ExecuteAfterFeature的最后場景,然后將標記的Before和After鈎子寫成如下來實現對BeforeFeature / AfterFeature掛鈎的模擬:

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

第一個答案的修改對我來說只用單引號

    Before('@feature_with_expensive_setup') do
      unless '@setup_is_done'
        # perform expensive setup code here ..
        @setup_is_done = true
      end
    end

您可以使用 at_exit 實現 after 功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM