2012-12-30 74 views
0

我不得不說我對Ruby和RSpec都是新的。無論如何,我完成了一個RSpec腳本,但重構後失敗了。原來這裏是工作的版本:爲什麼在此RSpec腳本中沒有正確傳遞對象引用?

describe Site do 
    browser = Watir::Browser.new :ie 
    site = Site.new(browser, "http://localhost:8080/site") 

    it "can navigate to any page at the site" do 
    site.pages_names.each do |page_name| 
     site.goto(page_name) 
     site.actual_page.name.should eq page_name 
    end 
    end 
    browser.close 
end 

這裏是修改的版本 - 我想報道所有被測試期間訪問過的網頁:

describe Site do 
    browser = Watir::Browser.new :ie 
    site = Site.new(browser, "http://localhost:8080/site") 

    site.pages_names.each do |page_name| 
    it "can navigate to #{page_name}" do 
     site.goto(page_name) 
     site.actual_page.name.should eq page_name 
    end 
    end 
    browser.close 
end 

在後一種情況下的問題是該網站在與「it」方法關聯的代碼塊中被評估爲零。 但是,當我這樣做:

... 
s = site 
it "can navigate to #{page_name}" do 
    s.goto(page_name) 
    s.actual_page.name.should eq page_name 
end 
... 

的零問題消失了,但測試失敗,「瀏覽器已關閉」的原因 顯然我失去了一些東西很基本的Ruby知識 - 因爲瀏覽器引用不是在正常工作修改腳本。我哪裏做錯了?應該使用什麼重構來完成這項工作? 感謝您的幫助!

回答

0

理解RSpec的,像許多Ruby程序,有兩個運行階段,這一點很重要:

  1. 在第一個階段,每一個RSpec的負載您的規格文件,並執行describecontext塊中的每一個。在這個階段中,代碼的執行定義了你的例子,鉤子等。但是你的例子和鉤子在這個階段不會被執行。
  2. 一旦RSpec完成加載規格文件(並且所有示例已被定義),它就會執行它們。

所以......你的榜樣修剪下來一個簡單的形式,這裏就是你的本事:

describe Site do 
    browser = Watir::Browser.new :ie 

    it 'does something with the browser' do 
    # do something with the browser 
    end 

    browser.close 
end 

雖然視覺上看起來的瀏覽器實例的實例,然後在本例中使用,然後關閉,這裏就是真的發生了:

  1. 瀏覽器實例的實例
  2. 的例子被定義(但不運行)
  3. 關閉瀏覽器
  4. (後來,所有的例子都被定義後......)的例子運行

由於O.Powell的回答表明,你可以關閉瀏覽器在after(:all)鉤延遲在此示例組中的所有示例都已運行之後關閉。也就是說,我會懷疑你是否真的需要定義時間的瀏覽器實例。通常,當示例在運行時需要它們時,最好是懶惰地創建資源(例如瀏覽器實例),而不是在示例定義階段。

+0

非常感謝你Myron!你的回答讓我大開眼界。事實上,我想要的是用每個塊定義幾個RSpec的例子,而不是單一的。現在你的解釋我看到我在做什麼錯誤,並能夠改變代碼做我想做的事情:) – tom

+0

蘇爾e,我很高興它有幫助! –

0

我使用假類爲Site和Watir複製了上面的代碼。它工作完美。那麼我唯一的結論就是這個問題必須存在於上述任一類中。我注意到Site實例只需訪問第一個工作版本中的一個頁面,但必須訪問非工作版本中的多個頁面。那裏涉及實例內部發生的突變可能存在問題。

看看這個有差別:

describe Site do 
    uri = "http://localhost:8080/site" 
    browser = Watir::Browser.new :ie 
    page_names = Site.new(browser, uri).page_names 

    before(:each) { @site = Site.new(browser, uri) } 
    after(:all) { browser.close } 

    pages_names.each do |page_name| 
     it "can navigate to #{page_name}" do 
     @site.goto(page_name) 
     @site.actual_page.name.should eq page_name 
     end 
    end 
    end 
+0

感謝您的建議,實際上我使用之前(:所有)和之後(:所有)鉤子,但我在代碼示例中刪除它們 - 因爲我不確定它們是否可能是問題的根源。讀Myron的答案 - 這根本不是聰明的想法..儘管你的答案顯示了比我提出的更好的編碼練習,我只能接受一個答案:(這次我決定了Myron的答案,因爲它幫助我更好地理解hook方法符合RSpec概念,我需要做些什麼來以編程方式定義示例.. – tom

相關問題