2014-03-01 246 views
1

我正在使用rspec和水豚爲我的Rails 4應用程序寫一些功能測試。我有它正常工作,但我正在努力弄明白這方面的測試的某些方面。rspec + capybara:功能測試每個測試只有1個期望?

我一直在閱讀,每個測試(它「應該...」塊)應該只測試1件事。好吧,這聽起來不錯,但是當我把這些付諸實踐時,我最終爲簡單的事情寫了大量的測試。

比方說,我有一個標準的註冊表格,需要電子郵件,密碼和信用卡。

因此,測試寫我的註冊功能測試,我必須寫3個單獨的測試來測試功能?

describe "Signup" do 
    it "informs user of an invalid email" do 
    visit signups_path 
    fill_in "Email", with: "" 
    click_button "Signup" 
    expect(page).to have_text("Email can't be blank") 
    end 
    it "informs user of an invalid password" do 
    visit signups_path 
    fill_in "Email", with: "[email protected]" 
    fill_in "Password", with: "" 
    click_button "Signup" 
    expect(page).to have_text("Password can't be blank") 
    end 
    it "informs user of an invalid credit card" do 
    visit signups_path 
    fill_in "Email", with: "[email protected]" 
    fill_in "Password", with: "valid-password" 
    fill_in "Card", with: "bogus" 
    click_button "Signup" 
    expect(page).to have_text("Card is invalid") 
    end 
end 

在單個測試中測試所有這些似乎更簡單。我正在努力尋找關於執行功能測試的正確方法的文章。我不想開始隨機編寫測試(1)實際上沒有覆蓋/測試我的代碼,或者(2)由於我無能地寫入而變得臃腫和緩慢。我瞭解測試的必要性,只是不確定如何最好地進行像上面那樣的功能測試。

+0

:您可以爲重複的代碼在每次測試開始時打動你調用指令來before,並提取helper方法? –

+0

@JustinKo,我認爲它會更簡單,因爲對於每個測試,我都在同一個「場景」中,每個測試都有很多重複的代碼。不過,在仔細研究一段時間後,我已經得出結論,清理'before'塊中的重複代碼有助於很多真正的測試應該只有1個'expect/assert'來真正幫助解決針點問題。通過「更簡單」我想我的意思是「更短」。但有時候更短並不總是更好。 –

回答

1

你應該幹掉你的代碼以減少重複。爲什麼你認爲它會更簡單寫一個測試

describe "Signup" do 
    before do 
    visit signups_path 
    end 

    def fill_form(fields = {}) 
    fields.each do |field_name, field_value| 
     fill_in field_name.to_s.capitalize, with: field_value 
    end 
    click_button "Signup" 
    end 

    it "informs user of an invalid email" do 
    fill_form email: "" 

    expect(page).to have_text("Email can't be blank") 
    end 
    it "informs user of an invalid password" do 
    fill_form email: "[email protected]", password: "" 

    expect(page).to have_text("Password can't be blank") 
    end 
    it "informs user of an invalid credit card" do 
    fill_form email: "[email protected]", 
       password: "valid-password", 
       card: "bogus" 

    expect(page).to have_text("Card is invalid") 
    end 
end 
+1

經過一段時間的研究,這是解決這個問題最清潔和最傳統的方法。嚴格地說,每個測試只能期望/堅持1件事才能真正成爲單元測試。這使每個單獨的測試更小,更容易維護。是否會導致運行測試套件的時間更長,但這是一個折衷。我只遇到了一種情況,我決定在單個測試中放置多個'expect(...)',這是因爲我正在調用一個外部API,並且在進行多個調用時這在時間上非常昂貴。 –