私は今、約3日間、これに対して頭をぶつけてきました。HTML ページをモデル化し、キュウリのステップ定義にフォーム データを入力する場所を指示するクラスを作成しました。
class FlightSearchPage
def initialize(browser, page, brand)
@browser = browser
@start_url = page
#Get reference to config file
config_file = File.join(File.dirname(__FILE__), '..', 'config', 'site_config.yml')
#Store hash of config values in local variable
config = YAML.load_file config_file
@brand = brand #brand is specified by the customer in the features file
#Define instance variables from the hash keys
config.each do |k,v|
instance_variable_set("@#{k}",v)
end
end
def method_missing(sym, *args, &block)
@browser.send sym, *args, &block
end
def page_title
#Returns contents of <title> tag in current page.
@browser.title
end
def visit
@browser.goto(@start_url)
end
def set_origin(origin)
self.text_field(@route[:attribute] => @route[:origin]).set origin
end
def set_destination(destination)
self.text_field(@route[:attribute] => @route[:destination]).set destination
end
def set_departure_date(outbound)
self.text_field(@route[:attribute] => @date[:outgoing_date]).set outbound
end
# [...snip]
end
ご覧のとおり、instance_variable_set を使用して参照をオンザフライで保持する変数を作成しました。変数の名前と値は構成ファイルによって提供されます (これは、必ずしも構成ファイルに精通していない人でも編集できるように設計されています)。ルビー)。
残念ながら、これは大きく毛むくじゃらのクラスであり、新しいフィールドを追加するたびにソース コードを編集する必要があります。これは明らかに設計が悪いため、さらに一歩進んで、 define_method を使用して変数名を動的に設定するメソッドと、これが、ここ数晩、午前 4 時まで起きていた原因です。
これは私がやったことです:
require File.expand_path(File.dirname(__FILE__) + '/flight_search_page')
class SetFieldsByType < FlightSearchPage
def text_field(config_hash)
define_method(config_hash) do |data|
self.text_field(config_hash[:attribute] => config_hash[:origin]).set data
end
end
end
新しいフィールドを追加するために必要なことは、YAML ファイルに新しいエントリを追加することだけであり、define_method は cucumber がデータを入力できるようにするメソッドを作成します。
現在、スコープに問題があります。Ruby は、define_method が @browser のメンバーであると認識しています。しかし、私が知りたいのは、これは実現可能ですか? define_method を完全に誤解していますか?