Ruby cucumber advance1
出自Eddie's Courses
目錄 |
建立腳本
熟悉了基本篇的操作之後,接下來我們在剛剛的那個feature裡面繼續再加一個scenario,大意是要「從文章列表頁,點擊"New Article"連結後,並在Title跟Content欄位填寫文字,按下Create按鈕送出,然後會看到應該看的東西」,腳本可以這樣寫:
Scenario: Create Article Given I have no articles And I am on the list of articles When I follow "New Article" And I fill in "Title" with "My First Title" And I fill in "Content" with "My First Content" And I press "Create" Then I should see "New Article Created!" And I should see "My First Title" And I should see "My First Content" And I should have 1 article
這看起來有點複雜,不過在cucumber/rspec裡做起來其實跟上一篇的做法差不多,就是測試、修改、再測試、再修改,有缺什麼undefined的,就補給它定義,MVC有缺的也照錯誤訊息一個一個的建立,直接全部通過為止。
開始測試
寫完腳本後,繼續重複測試的指令cucumber features:
2 scenarios (1 undefined, 1 passed) 14 steps (8 skipped, 2 undefined, 4 passed) 0m0.094s
上面我省略了一些錯誤訊息,總之目前有2個scenario,14個測試裡有4個已經過了(就是我們上一篇的那4個),然後2個undefined,後面有8個先跳過,即然undefined,那我們就一樣來加一下定義吧。
錯誤訊息給的2個undefined的指示, 第一段:
Given /^I have no articles$/ do pending # express the regexp above with the code you wish you had end
這個可以改成:
Given /^I have no articles$/ do Article.delete_all end
就把Article model裡的東西清掉就行了,第二段:
Then /^I should have 1 article$/ do pending # express the regexp above with the code you wish you had end
不過我們這裡做一些修改:
Then /^I should have ([0-9]+) article$/ do |count| Article.count.should == count.to_i end
這裡把那個數字1改用RE做表示,然後去比對Article model的數字,這裡最後加了一個to_i是因為這裡當cucumber在傳參數的時候,它會以字串的方式傳進來,所以先做個轉型再來跟count做比對。
建立表單
完成定義後再跑一次測試應該會發現我們又往目標前進一步了(為了能更清楚找到錯誤的地方,下面我省略了一些比較不必要的訊息)
When I follow "New Article" # features/step_definitions/web_steps.rb:26
Could not find link with text or title or id "New Article" (Webrat::NotFoundError)
2 scenarios (1 failed, 1 passed)
14 steps (1 failed, 7 skipped, 6 passed)
0m0.100s
這次的錯誤訊息是找不到"New Article"這個連結,所以我們準備就來在列表頁加個連結給它。
檔案:app/views/articles/show.html.erb
<% for article in @articles %> <%=h article.title %> <% end %> <p><%= link_to "New Article", new_articles_path %></p>
連結加在哪裡都沒關係,它會自己找的到在哪。
Controller的部份也要加一下
檔案:app/controllers/articles_controller.rb
def new @article = Article.new end
接著要來做表單的部份
檔案:app/views/articles/new.html.erb
<% form_for @article do |f| -%> <p> <%= f.label :title %><br /> <%= f.text_field :title %> </p> <p> <%= f.label :content %><br /> <%= f.text_field :content %> </p> <p class="button"><%= f.submit "Create" %></p> <% end -%>
為了展示目的,基本上這裡沒用到太複雜的Rails寫法,大多是簡單的CRUD,也沒做太多的驗證跟檢查。
繼續測試
表單做好了,繼續測試流程:
And I press "Create" # features/step_definitions/web_steps.rb:22
No action responded to create. Actions: index, new, and show (ActionController::UnknownAction)
2 scenarios (1 failed, 1 passed)
14 steps (1 failed, 4 skipped, 9 passed)
0m0.124s
又少了幾個錯誤訊息了,而這次的錯誤訊息是找不到對應的action,所以接著是建立所需要的action給它。
def create @article = Article.create(params[:article]) flash[:notice] = "New Article Created!" redirect_to articles_path end
繼續測試
And I press "Create" # features/step_definitions/web_steps.rb:22
Then I should see "New Article Created!" # features/step_definitions/web_steps.rb:142
expected the following element's content to include "New Article Created!":
My First Title
New Article.
2 scenarios (1 failed, 1 passed)
14 steps (1 failed, 3 skipped, 10 passed)
0m0.199s
會發現又過了一個測試,這次錯誤訊息是沒有在view看到應該要看的flash訊息跟字樣,所以接著我們修改一下show view:
檔案:app/views/articles/show.html.erb
<p><%= flash[:notice]%></p> <% for article in @articles %> <%=h article.title %> <%=h article.content %> <% end %> <p><%= link_to "New Article", new_articles_path %></p>
一般我們應該是會把flash訊息放在layout裡,不過這裡為了展示目的就偷懶的把它隨便找個地方加一下,並且也把content欄位的東西給印出來。 再跑一下測試:
% cucumber features
Feature: Manage Articles
In order to make a blog
As an author
I want to create and manage articles
Scenario: Articles List # features/manage_article.feature:6
Given I have articles titled Pizza, Breadsticks # features/step_definitions/article_steps.rb:1
When I go to the list of articles # features/step_definitions/web_steps.rb:18
Then I should see "Pizza" # features/step_definitions/web_steps.rb:142
And I should see "Breadsticks" # features/step_definitions/web_steps.rb:142
Scenario: Create Article # features/manage_article.feature:12
Given I have no articles # features/step_definitions/article_steps.rb:7
And I am on the list of articles # features/step_definitions/web_steps.rb:14
When I follow "New Article" # features/step_definitions/web_steps.rb:26
And I fill in "Title" with "My First Title" # features/step_definitions/web_steps.rb:34
And I fill in "Content" with "My First Content" # features/step_definitions/web_steps.rb:34
And I press "Create" # features/step_definitions/web_steps.rb:22
Then I should see "New Article Created!" # features/step_definitions/web_steps.rb:142
And I should see "My First Title" # features/step_definitions/web_steps.rb:142
And I should see "My First Content" # features/step_definitions/web_steps.rb:142
And I should have 1 article # features/step_definitions/article_steps.rb:11
2 scenarios (2 passed)
14 steps (14 passed)
0m0.200s
喔!! 全部過了!!
結論
測試先行開發的原則大概就是「先寫測試 ,再寫程式」,然後邊測邊改、邊改邊測,測試通過了,你的程式也寫好了,反過來說,程式寫好了,你的測試也寫好了。TDD在網路上可以找到許多介紹它優缺點的文章,我想最大的缺點就是比一般的寫程式方法更花時間,花的時間會是原來的2倍以上(當然這也要看個人的熟練度),我個人的看法是,如果你是打算這個網站將來會長期經營維護的,前面測試所花的投資絕對是值得的。
若有任何錯誤或建議,歡迎來信指教 :)
eddie
