2017-06-29 26 views
1

背景黃瓜紅寶石 - 在一個模塊內的臺階

我用各種不同的步驟,在多個項目中使用兩種寫黃瓜庫,並試圖通過他們的分裂成3,以減少步驟定義複雜不同的模塊,適用於iOS,Android和網絡 - 特別是包括所有3.

一個步驟庫將包括基於安全的步驟負荷的項目,我想明確地包含進使用的步驟之前的項目。

if $profile[:app_type] == 'android' 
    World(ProjectSteps::Android) 
else 
    if $profile[:app_type] == 'ios' 
     World(ProjectSteps::IOS) 
    else 
     World(ProjectSteps::Web) 
    end 
end 

這些不更換輔助方法,但給我們節省時間,新項目啓動時:

該項目分庫將根據什麼在配置中規定被明確列入也將讓我們有寫在這取決於我們是否正在測試的網絡,本地iOS應用或內置有完全相同的功能原生Android應用程序不同的方式項目的具體步驟的定義,但有足夠的不同需要不同的步驟定義

的問題

定義模塊中的步驟後,該功能的文件仍然可以執行這個令人高興的是,即使模塊沒有被列入「世界」是這樣的:World(CommonSteps::Security),這是你平時會用於讓黃瓜知道隱藏在模塊內部的輔助方法。

When 'I provide my personal details' do 
    select :title, 'Mr' 
    fill :first_name, 'John' 
    fill :last_name, 'Doe' 

    unless $profile[:app_type] == 'web' 
     click :progress 
    end 

    if $profile[:app_type] == 'android' 
     fill :postcode, 'TE37ER' 
     select :address, '1 Test Street' 
     click :progress 
     fill :occupation, 'Tester' 
     fill :company, 'Test Company' 
     click :progress 
    else 
     fill :occupation, 'Tester' 
     fill :company, 'Test Company' 
     unless $profile[:app_type] == 'web' 
      click :progress 
     end 
     fill :postcode, 'TE37ER' 
     select :address, '1 Test Street' 
     click :progress 
    end 
end 

這一步定義一次嘗試測試3個應用程序,但它正在測試完全相同的功能,完全一樣的場景和完全相同的功能。如果這被分成3個步驟定義,那麼將來調試會更簡單,但同一個功能文件可以用於每個定義(這不是沒有問題的,因爲有很多應用程序它們在網絡和原生移動版本中共享完全相同的功能)。在我看來,這種類型的步驟定義試圖實現太多。

儘管是更多這將是更容易維護,因爲它是簡單的:

module ProjectSteps::IOS 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     click :progress 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     click :progress 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
    end 
end 
module ProjectSteps::Android 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     click :progress 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     click :progress 
    end 
end 
module ProjectSteps::Web 
    When 'I provide my personal details' do 
     select :title, $user[:title] 
     fill :first_name, $user[:first_name] 
     fill :last_name, $user[:last_name] 
     fill :occupation, $user[:occupation] 
     fill :company, $user[:company] 
     fill :postcode, $user[:postcode] 
     select :address, $user[:line1] 
     click :progress 
    end 
end 
When 'some thing that is the same across platforms' do 
    # Some stuff 
end 

請記住,這是我想要實現一個簡單的版本,並沒有顯示我試圖解決的一些問題的完全複雜性。在這種情況下,我很可能會使用if/unless版本而不是拆分版本,但是有幾種情況極其複雜,並且可以從拆分爲3個部分中受益。

我們還可以爲我們在開發過程中發現的錯誤添加靜默檢查,以確保這些不會退步,並且隨着web,android和ios應用程序具有不同的錯誤,我們最終會得到大量if/unless聲明。

我試過了什麼?- 我聽到你問

嗯,我要麼真的關閉或真的爲期不遠。

GivenWhenThen不同的模塊,這就是爲什麼我不得不尋找,我相信他們是一個別名的方法中時不能按預期工作。

下面是結果代碼:

require_relative 'xss.rb' 
require 'cucumber' 

module CommonSteps 
    module Security 
    Cucumber::RbSupport::RbDsl.register_rb_step_definition(
     'I attempt to write a step definition that has to be included to work', 
     Proc.new { 
      # Some stuff here 
     }) 
    end 
end 

寄存器的步驟定義精絕。但這是問題的一部分。我只想註冊該步驟定義,如果該模塊已包含在我正在開發的項目的世界中。

這也意味着如果我們需要,我們可以切換iOS和Android步驟的Web步驟,同時保持功能文件完全相同。 (是的,我知道if陳述的事情,但也嫌多,一步DEFS得到真快複雜。)

編輯

我想要實現的是不喜歡「網站的步驟」是我們已經看到過去。沒有通用步驟顯示代碼,只有我們與開發團隊一起同意與我們合作的業務的語言。由於我們工作的很多項目都是跨平臺的,我本質上試圖實現將切換使用哪種類型的步驟定義的方法。 - 如果您使用的是Chrome,請使用此步驟定義的Web版本,如果您使用的是iOS,請使用此步驟定義的iOS版本,但也可以包含各種通用步驟,它可以鏈接回我們的頁面對象模型 - 保持場景完全基於業務。

Given I am on the "Personal Details" page # (generic) 
When I provide my personal details # (non-generic, but Web, iOS and Android versions exist) 
But leave the "First Name" field blank # (generic) 
And I attempt to continue to the next page # (generic) 
Then I should see a validation error for the "First Name" text box stating: "Please provide your first name" # (generic) 

例如,如果確認是什麼,企業想知道是否正常工作,並已同意企業的要求it'a部分,是有交流的更多的業務理解的方式那些信息? - 爲什麼我們要確保用戶填寫信息以便驗證不顯示,但是如果他們沒有提供這些信息,我們也應該測試出現的驗證需要的場景。

我們使用頁面對象模型時,「個人詳細信息」將在urls地圖中找到:personal_details鍵。密鑰可以傳遞到下一步,鏈接到包含:first_name密鑰的Pages.personal_details方法。我們所有的項目都使用這種設置,它是我們的核心幫助程序庫的文檔的一部分。

我想要達到的效果並不一定是不好的做法,如果以我建議的方式使用,但如果使用不正確,則可能會這樣使用。

回答

-1

在黃瓜歷史上已經有很多次,當這樣的事情已經完成時,黃瓜本身曾經有過網絡步驟,前一段時間被刪除。這些現在在Gem https://github.com/cucumber/cucumber-rails-training-wheels。你可能會從你的庫中得到一些提示。

這就是說,我強烈建議不要編寫一個步驟定義庫。相反,我會寫一個可以被步驟定義使用的方法庫。粗略的例子可能有助於說明這一點。

可以說你有一個非常複雜的方法登錄到應用程序。你可以寫一個真正commplicated步驟定義,隨着各種東西記錄,如

When I login (hugely complex regex to deal with things like ... # loads of code to deal with you params and regex's and make things work with lots of different scenarios

或交易,你可以寫一個方法,像

def login(as:, args={})

,讓人們用這個方法當他們寫東西,例如

When 'I login' do 
    login as: @i 
end 

When 'I login as Fred' do 
    login as: create_or_find_user(firstname: 'Fred') 
end 

When 'I login as Fred with Jill's password' do 
    login as: @fred, password: @jill.password 
end 

輔助方法提供了實用程序來幫助你編寫簡單的步驟定義是切合閣下個別情況下。共享步驟定義限制您使用高度複雜且不能具有任何特定上下文的內容。

場景應該是上下文特定的,並且允許靈活簡單的語言,它是特定於他們所屬的單個世界的上下文的。他們應該是所有關於爲什麼正在完成的事情,那是什麼,並沒有關於如何做的事情。根據定義,它們不共享,因此從定義上講也不是分步定義。

一旦你通過調用你進入的代碼領域留下了步驟定義和代碼是真正有效的共享

黃瓜瞭解到,共享的步驟定義是一個非常糟糕的主意的教訓(見http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off)。謹防重複過去的錯誤。

+1

這些步驟庫適用於導航到網址,安全測試和API測試等內容,這些內容可能非常通用,適用於內部目的。但是,它們只是可以通用而不顯示任何代碼的功能文件。我明白寫出的步驟更像是:當我用「Bar」填充「#foo」時,這是非常糟糕的做法,這就是爲什麼我已經不再使用它了。 –

+0

閱讀鏈接的文章,並考慮重新閱讀我的答案。一個場景中永遠不應該有一個URL,那就是你在做什麼,而不是爲什麼。 API的應用場景不應該關於你如何調用API,他們應該是關於你爲什麼要調用API。真的沒有通用的場景!整個場景的目的是寫出一些特定於世界的事物,這就是爲什麼Cucumber:World被稱爲世界,爲什麼事物是全球性的。場景中的每件事情都應該針對世界,世界上不應該有任何歧義。 – diabolist

+0

也許考慮給出具體的例子,您可以在單獨的問題中看到一些通用的步驟,我們可以更詳細地看一看 – diabolist