2010-12-08 106 views
10

我正在使用黃瓜+水豚進行一些網絡自動化測試。我希望能夠連接我自己的標籤(類似於@all_browsers之前的情況),並將其與我設置的Web驅動程序(celerity,firefox上的selenium,即chrome)的列表運行。我不想在前面用4種不同的標籤寫4種不同的情況。我看着試圖用一個新的驅動程序通過我註冊這樣做:有沒有人想出了在多個瀏覽器/網絡驅動程序上運行相同黃瓜場景的方法?

Capybara.register_driver :all_browsers do |app| 
# What would even work in here? I don't think anything will. 
end 

然後用下面一句話:

Before('@all_browsers') do 
# Same problem here. 
end 

但我不能肯定要放什麼東西在在實際上可能工作的方法之前。

我用黃瓜鉤試過,具體如下:

Around('@all_browsers') do |scenario, block| 
    Capybara.current_driver = :selenium_firefox 
    block.call 

    Capybara.current_driver = :selenium_chrome 
    block.call 
    # etc 
end 

但是我所希望的,這並不表現。它使用相同的驅動程序並使用它運行該場景兩次。

沿鉤線以下,有這個從黃瓜文檔:
You may also provide an AfterConfiguration hook that will be run after Cucumber has been configured. This hook will run only once; after support has been loaded but before features are loaded. You can use this hook to extend Cucumber, for example you could affect how features are loaded...
這可能是往下走的這一個潛在的路徑,但我還沒有設法拿出任何東西,無論是在這裏工作。

我研究過自定義格式化程序,但他們真的只是看起來像他們那樣做 - 格式化輸出,而不是指定功能如何實際運行。

我已經看着最重要的黃瓜的特徵跑步者,但這看起來並不容易或友好。
請幫忙嗎?任何人?

回答

9

所以,我結束了自己的解決方案。不知道是否這是最好的或最簡潔的方法,但其實我只是清盤:

  1. 抽象所有的公共環境中的東西變成env.rb
  2. 使用黃瓜型材這就需要一個特定的環境文件(如Firefox。 rb)需要env.rb,然後將Capybara的默認驅動程序設置爲適當的驅動程序。
  3. 寫了一個大的ol'thor類,其中包含捆綁一堆黃瓜命令的任務,並呼籲使用正確的配置文件運行壞男孩。
  4. 寫了一個捆綁命令的'all_browsers'任務,然後調用每個特定的驅動程序任務,所以現在我可以有一個任務運行我在所有支持的驅動程序上提供的任何一組場景。

工作就像一個魅力,我認爲可能實際上已經結束了,到底比任何我在上面試圖更好,因爲雷神文件我能夠添加一些東西像一個標杆的選擇,以及是否內不要將功能分解成多個線程。 仍然好奇,如果有人想出了這個解決方案雖然。

cucumber.yaml:
這裏,all_features文件少了點在.feature結束一切的水珠,因爲如果我在整個功能目錄拉,將在一切拉之下,包括所有的個人資料文件等,這不是我想要的,因爲每個配置文件將默認水豚驅動程序設置爲不同的值。一旦你指定-r作爲黃瓜的選項,全部自動加載任何文件被暫停。

default: --format pretty 

chrome: --format pretty -r features/support/profiles/chrome.rb -r features/all_features -r features/step_definitions 

firefox: --format pretty -r features/support/profiles/firefox.rb -r features/all_features -r features/step_definitions 

celerity: --format pretty -r features/support/profiles/celerity.rb -r features/all_features -r features/step_definitions 

firefox.rb(以下簡稱 '個人資料' 的文件):

require File.dirname(__FILE__) + "/../env.rb" 

Capybara.configure do |config| 
    config.default_driver = :selenium_firefox 
end 

selenium_firefox.rb(其中我註冊驅動程序,並設置我已經清盤不需要現在有些標籤能力,作爲@selenium_firefox標籤是我在這個原始的企圖的一部分問題發佈):

# Register a specific selenium driver for firefox 
Capybara.register_driver :selenium_firefox do |app| 
    Capybara::Driver::Selenium.new(app, :browser => :firefox) 
end 

# Allows the use of a tag @selenium_firefox before a scenario to run it in selenium with firefox 
Before('@selenium_firefox') do 
    Capybara.current_driver = :selenium_firefox 
end 

feature_runner.thor:

require 'benchmark' 

class FeatureRunner < Thor 
    APP_ROOT = File.expand_path(File.dirname(__FILE__) + "/../") 

    # One place to keep all the common feature runner options, since every runner in here uses them. 
    # Modify here, and all runners below will reflect the changes, as they all call this proc. 
    feature_runner_options = lambda { 
    method_option :verbose, :type => :boolean, :default => true, :aliases => "-v" 
    method_option :tags, :type => :string 
    method_option :formatter, :type => :string 
    method_option :other_cucumber_args, :type => :string 
    } 


    desc "all_drivers_runner", "Run features in all available browsers" 
    method_option :benchmark, :type => :boolean, :default => false 
    method_option :threaded, :type => :boolean, :default => true 
    feature_runner_options.call # Set up common feature runner options defined above 
    def all_drivers_runner 
    if options[:threaded] 
     feature_run = lambda { 
     thread_pool = [] 

     t = Thread.new do |n| 
      invoke :firefox_runner 
     end 
     thread_pool << t 

     t = Thread.new do |n| 
      invoke :chrome_runner 
     end 
     thread_pool << t 

     t = Thread.new do |n| 
      invoke :celerity_runner 
     end 
     thread_pool << t 

     thread_pool.each {|th| th.join} 
     } 
    else 
     feature_run = lambda { 
     invoke "feature_runner:firefox_runner", options 
     invoke "feature_runner:chrome_runner", options 
     invoke "feature_runner:celerity_runner", options 
     } 
    end 

    if options[:benchmark] 
     puts "Benchmarking feature run" 
     measure = Benchmark.measure { feature_run.call } 
     puts "Benchmark Results (in seconds):" 
     puts "CPU Time: #{measure.utime}" 
     puts "System CPU TIME: #{measure.stime}" 
     puts "Elasped Real Time: #{measure.real}" 
    else 
     feature_run.call 
    end 
    end 

    desc "firefox_runner", "Run features on firefox" 
    feature_runner_options.call # Set up common feature runner options defined above 
    def firefox_runner 
    command = build_cucumber_command("firefox", options) 
    run_command(command, options[:verbose]) 
    end 

    desc "chrome_runner", "Run features on chrome" 
    feature_runner_options.call # Set up common feature runner options defined above 
    def chrome_runner 
    command = build_cucumber_command("chrome", options) 
    run_command(command, options[:verbose]) 
    end 

    desc "celerity_runner", "Run features on celerity" 
    feature_runner_options.call # Set up common feature runner options defined above 
    def celerity_runner 
    command = build_cucumber_command("celerity", options) 
    run_command(command, options[:verbose]) 
    end 

    private 
    def build_cucumber_command(profile, options) 
    command = "cd #{APP_ROOT} && ./bin/cucumber -p #{profile}" 
    command += " --tags=#{options[:tags]}" if options[:tags] 
    command += " --formatter=#{options[:formatter]}" if options[:formatter] 
    command += " #{options[:other_cucumber_args]}" if options[:other_cucumber_args] 
    command 
    end 

    def run_command(command, verbose) 
    puts "Running: #{command}" if verbose 
    output = `#{command}` 
    puts output if verbose 
    end 

end 

,一切結束了,相對於根目錄:

輸出的
. 
|____cucumber.yml 
|____features 
| |____all_features.rb 
| |____google_search.feature 
| |____step_definitions 
| | |____google_steps.rb 
| | |____web_steps.rb 
| |____support 
| | |____custom_formatters 
| | | |____blah.rb 
| | |____env.rb 
| | |____paths.rb 
| | |____profiles 
| | | |____celerity.rb 
| | | |____chrome.rb 
| | | |____firefox.rb 
| | |____selenium_drivers 
| | | |____selenium_chrome.rb 
| | | |____selenium_firefox.rb 
| | | |____selenium_ie.rb 
| | | |____selenium_remote.rb 
| | |____selenium_drivers.rb 
|____tasks 
| |____feature_runner.thor 
| |____server_task.rb 

thor -T

feature_runner 
-------------- 
thor feature_runner:all_drivers_runner # Run features in all available browsers 
thor feature_runner:celerity_runner  # Run features on celerity 
thor feature_runner:chrome_runner  # Run features on chrome 
thor feature_runner:firefox_runner  # Run features on firefox 

現在我可以運行類似:
thor feature_runner:all_drivers_runner --benchmark
這將運行所有在每個駕駛員的線程中爲所有水豚駕駛員提供特色功能,從而獲得結果。

或者
thor feature_runner:celerity_runner
這隻會在運行波速所有功能。

但我現在還可以提供一些其他的選項,從而獲得傳遞到黃瓜,如雷神命令:
[email protected]_browsers
--formatter=hotpants
--other_cucumber_args="--dry-run --guess --etc"

功能的文件現在可以是什麼樣子:

Feature: Start up browser 
    @all_browsers 
    Scenario: Search Google 
    Given I am on the home page 
    When I fill in the search bar with "Capybara" 
    And I press "Search" 
    Then I should see "Capybara" 

似乎很多設置,但現在如果我用@all_browsers標記功能,我可以構建一個套件來測試所有水豚驅動程序,在多線程環境中,一個雷神命令:
thor feature_runner:all_drivers_runner --threaded [email protected]_browsers

或建立了一個在快速性運行冒煙測試套件:
thor feature_runner:celerity_runner [email protected]_test

0

這可以通過SauceLabs的託管服務來實現。 Cucumber Sauce寶石爲您提供平行的多瀏覽器測試。

或者,如果您想自己實施,也許可以從該寶石的來源借用。

+0

所以這似乎與硒有關。我希望能夠對付水豚支持的任何驅動程序 - 特別是速度。這裏的代碼也沒有太多,我懷疑事情的背後有很多問題。 – bergyman 2010-12-08 17:37:33

+0

那麼你有「硒」標籤,但不是「celerity」標籤。 – 2010-12-08 19:06:43

+0

採取了點。 celerity標籤添加。應該澄清,我想運行它反對硒和迅速。 – bergyman 2010-12-08 21:28:51

0

這裏是我的黑客: (我的情況證明一個功能與JavaScript和JavaScript關閉)

  1. 將每個方案放入其自己的功能文件。
  2. 將除最後一行之外的每一行移至「背景:」部分。
  3. 把最後一行到一個場景每個瀏覽器
  4. 標籤中的每個場景適當

    Feature: a feature 
    
    Background: 
    Given a user "Jim" exists 
    Given a user "Mike" exists 
    
    When I login as "mike" 
    And I follow "Lesson 1" 
    
    And I follow "Upload a video" 
    Then "#upload_a_video" should be active 
    
    And I fill in "video_title" with "my film" 
    And I attach the file "video.mov" to "video_upload" 
    And I press "Post" 
    
    Scenario: normal 
    And I should see "my film" 
    
    @javascript 
    
    Scenario: javascript 
    And I should see "my film" 
    
0

我這樣做是「的Watir」項目建議的方式。我在Rake文件使用require parallel_cucumber,然後將每個場景黃瓜都有自己的並行線程(最多20在這種情況下):

task :run_cucumber do 
    FileUtils.mkpath(ENV['OUT_DIR']) 
    begin 
    # cannot format report as HTML because of parallel forking 
    threads = 20 
    @result = system "parallel_cucumber features -o \"--format junit --out #{ENV['OUT_DIR']} --format pretty --tag @sauce\" -n #{threads}" 
    ensure 
    @success &= @result 
    end 
end 

然後,你的黃瓜項目的剩餘部分可以寫像往常一樣!很簡單!我的完整示例在這裏:https://github.com/djangofan/cuke-parallel-starter