2016-12-28 68 views
0

我是使用Ruby自動化測試的新手(與Selenium結合使用),並努力在我的test_steps.rb中使用常量的名稱而不是它的值。Ruby:如何使用常量名稱而不是它的值

我使用了3個文件如下:

LoginPage.rb

class LoginPage < Base 

    FIELDS = { 
    'Username' => '//form[@id="login"]//input[@name="j_username"]', 
    } 

Base.rb

def fill_field(field, value) 
    find(:xpath, field, wait: 15).set(value) 
    #logger("Filling field with xpath '" + field + "' with value '" + 
      value + "'.") > this works fine but prints the xpath 

    p "field: " + field 
    log = field.scan(/\w+(?:'\w+)*/).last 
    logger("Filling field '" + log + "' with value '" + value + "'.") 

test_steps.rb:

And(/^logs in as user "([^"]*)"$/) do |userName| 
    $login_name = search_excel('testdata/accounts.xlsx', userName, 1) 
    @pg.fill_field(LoginPage::FIELDS['Username'], $login_name) 

當execu婷場景我看到這在我的命令提示符:

Given a user is on the oCRM login page # features/step_definitions/test_steps.rb:13 
"field: //form[@id=\"login\"]//input[@name=\"j_username\"]" 
28/12/2016 13:03:50 Filling field 'j_username' with value 'D0X02703'. 

注意,在Base.rb打印爲常量匹配「場」

'//form[@id="login"]//input[@name="j_username"]' 

我想它打印的常量本身的價值線:"LoginPage::FIELDS['Username']"。我們的目標是在我的日誌記錄,以打印:

"Filling field 'Username' with value 'DOX02703'." 

我試着打印"field.name""field.value"local_variables玩耍了,但還沒有成功。幫助將非常歡迎!

也嘗試了其他方式下面的定義,但ofcourse那麼它不會拿起恆定值,並查找的XPath "LoginPage::FIELDS['Username']"

def fill_fields(page, type, field, value) 
      find(:xpath, page + "::" + type + "['" + field + "']", wait: 15).set(value) 
+0

我想,這可能會爲你做它,假設你排除值印刷的一部分! http://stackoverflow.com/q/2603617/6090706 –

+0

感謝您的評論!我更喜歡不使用我不明白的代碼(或者看起來過於複雜),所以我不會這樣做。也許只需在日誌中打印xpath即可:-) – Blapmeister

+0

最好不要使用你不明白的代碼,但如果你試圖理解它,你將會學到一些或未來的事情 –

回答

0

本質上說是叫

@pg.fill_field(LoginPage::FIELDS['Username'], $login_name) 

username = LoginPage::FIELDS['Username'] 
@pg.fill_field(username, $login_name) 

這只是第一個沒有沒有區別提到臨時變量。無論哪種方式,傳遞給該方法的唯一東西是與哈希中的「用戶名」鍵關聯的值。看看你的類結構看起來好像你有許多從頁面繼承的'Page'類,並且你期望fill_field在繼承它的類中使用FIELDS常量。在這種情況下,你可能想

def fill_field(field, value) 
    find(:xpath, self.class::FIELDS[field], wait: 15).set(value) 

    logger("Filling field '" + field + "' with value '" + value + "'.") 
end 

,把它作爲

@pg.fill_field('Username', $login_name) 
+0

看起來不錯,但恐怕這不適合我。起初我得到了這個消息,因爲我們沒有在基礎中定義常量。rb:'未初始化的常量Base :: FIELDS(NameError)' 在base.rb中添加「FIELDS + {}」後,我得到'InvalidSelectorError:由於以下錯誤無法找到包含xpath表達式的元素。 (因爲在base.rb中沒有常量「用戶名」) 這應該怎麼知道Page類尋找常量?我是否需要在每個Page對象中使用def fill_field而不是在base.rb中? – Blapmeister

+0

@Blapmeister只要你在從Base派生的Page類的對象上調用fill_field,那麼'self.class :: FIELDS'應該引用Page類中的FIELDS常量,因爲那是實際的類對象,並且對常量的所有訪問都需要採用'self.class :: FIELDS'形式。如果你在Base類的純對象(不是從Base派生的類)上調用它,它將不起作用 –

+0

非常感謝Thomas!得到它的工作方式,請參閱下面的設置。現在唯一困擾我的是我必須在每個頁面對象上放置def fill_field。以前頁面對象不包含類,只包含常量。但是由於實際的功能仍然在base.rb中,我不認爲這是一個問題。 – Blapmeister

1

常量不是Ruby對象。既然你只能傳遞對象作爲參數,並且只能調用對象的方法(而對象是唯一的值,而方法調用是唯一的方法),所以傳遞一個常量作爲參數或者詢問它是不可能的爲它的名字。

你唯一可以做的就是不斷的通過名作爲參數的代替或補充對象不斷點。

+0

絕對常數是Ruby中的對象,只是用戶已經在常量哈希上調用了'#[]'方法並且檢索了給定鍵的值,所以沒有對傳遞給該方法的常量的引用。 –

+0

常量是* not *對象。例如。請參閱ISO Ruby語言規範的第6.2.1節,它明確指出(** bold ** emphasis mine):「一個變量用名稱表示,而**表示**一個對象,它被稱爲變量 **變量本身不是對象**。「或者,請參閱matz本人(** bold **強調我自己)合着的書「Ruby編程語言」:「每個**值**都是一個對象」。注意:它表示每個*值*,變量不是值。常量是各種變量。爲什麼'Module#constants'返回'Symbol'的'Array'而不是'Constants'的'Array'? –

+0

因爲它不能!它不能返回'常量'數組,因爲常量不是對象,數組必須包含對象。爲什麼'Module#const_get','Module#const_set','Module#const_defined?','Module#const_get','Module#deprecate_constant','Module#private_constant','Module#public_constant'和'Module#remove_const ',把表示常數名稱的'Symbol'作爲一個參數,而不是簡單地直接表示常量?因爲方法只能將對象作爲參數,常量不是對象。我不知道爲什麼這是如此有爭議。 *任何*主流主流語言的常量和變量不是對象 –

0

你可以使用與const_get的字符串:

class LoginPage # <Base 
    FIELDS = { 
    'Username' => '//form[@id="login"]//input[@name="j_username"]', 
    } 
end 

def get_constant_from_string(param) 
    puts "Parameter is #{param}" 
    Object.const_get(param) if param.is_a?(String) 
end 

get_constant_from_string(LoginPage::FIELDS) 
# Parameter is {"Username"=>"//form[@id=\"login\"]//input[@name=\"j_username\"]"} 
# method returns nil 

puts get_constant_from_string("LoginPage::FIELDS")['Username'] 
# Parameter is LoginPage::FIELDS 
# //form[@id="login"]//input[@name="j_username"] 
+0

我已經嘗試過這一點,但無法使其工作。要設置參數,我將不得不連接值,導致它將查找xpath「LoginPage :: FIELDS ['Username']」而不是常量。我的Ruby體驗(總體編程經驗)很少,所以我可能會誤解。 – Blapmeister

0

工作液根據托馬斯·沃波爾的評論:

Base.rb

def find_field(field) 
    @fieldToFill = find(:xpath, self.class::FIELDS[field], wait: 15) 
end 

def set_value(value) 
    @fieldToFill.set(value) 
end 

def fill_field_log(field, value) 
    logger("Filling field '" + field + "' with value '" + value + "'.")   
end 

LoginPage.rb

def fill_field(field, value) 
    find_field(field) 
    set_value(value) 
    fill_field_log(field, value) 
end 

test_steps.rb

Given(/^a user is on the login page$/) do 
    @pg = Base.new 
    @lp = LoginPage.new 
    @pg.visit_loginpage 
end 

And(/^logs in as user "([^"]*)"$/) do |userName| 
    $login_name = search_excel('testdata/accounts.xlsx', userName, 1) 
    login_password = search_excel('testdata/accounts.xlsx', userName, 2) 

    @lp.fill_field('Username', $login_name) 
    @lp.fill_field('Password', login_password) 
相關問題