使用Cucumber+Rspec玩转BDD(2)——邮件激活
生活随笔
收集整理的這篇文章主要介紹了
使用Cucumber+Rspec玩转BDD(2)——邮件激活
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用Cucumber+Rspec玩轉BDD(2)——郵件激活
2009年3月2日 星期一
### 溫故知新 ###
??? 前面我們已經完成了新用戶注冊功能的開發,為了方便我們后面的開發工作且不擾亂之前的工作成果,我們先將這份源代碼歸檔并做個標記。
??? 為了獲得更好的閱讀體驗,讀者朋友們可以在這里下載源碼:http://github.com/404/bdd_user_demo/tree/master
### 提交工作成果到GIT倉庫 ###
??? $ cd ~/code/user_demo
??? $ git init
??? $ git add .
??? $ git commit -m?"A user can be able to sign up."
??? $ git tag v1
??? “git init” 會在 ~/code/user_demo 目錄中初始化版本庫;接著 “git add .” 將 user_demo 目錄中的所有文件信息編入索引(index files);然后 “git commit” 命令將根據 index 中的信息將工作內容提交到項目的GIT倉庫里邊去,-m 選項加上了本次提交的一些說明;最后 “git tag” 給這次提交所生成的版本號標記了一個別名叫 v1。
??? 其實好習慣是在新建rails-app后就初始化版本庫。由于篇幅的關系,筆者才將些許GIT的內容放到這篇文章中。這不,正好派上用場嘍!
??? 在主干(master)上工作是危險的,因為控制的不夠好會擾亂版本,這不是我們愿意看到的。為此,GIT允許我們在主干道的基礎上建立新的分支(branch),在分支中進行開發工作,這樣好控制風險。比如有時候分支中的工作搞得一塌糊涂,開發人員想重來的時候,直接丟掉刪除這個分支再新建一個工作分支重新工作就是了,這對項目中的主干完全沒有絲毫影響(不會擾亂你上次提交到master中的工作成果),等你在新分支中開發完畢后,再將這個分支中的工作成果歸并到主干中就行。GIT的分支告訴我們,丟掉一個爛攤子比收拾一個爛攤子要輕松得多;潛意識里,我們幾乎一致認為這對開發人員的大腦是友好的!:)
??? 下面我們在主干的基礎上為后面郵件激活這個功能的開發新建一個分支。
### 新建工作分支 ###
????$ git checkout -b email_activation
??? 或者,
????$ git branch email_activation
????$ git checkout email_activation
??? 查看當前工作所在的分支,
????$ git branch
??? 會返回項目中的所有分支,前面加星*就是當前的工作分支。
??? 做開發要步步為營,不是嗎?git可以很方便地幫我們做到這點。在歸檔源碼后,接著我們新建了一個名為 email_activation 的分支,并將當前的工作狀態從master主干切換到email_activation分支中。這里說明下,此時的 email_activation 相當于之前源碼(v1)的一份副本,這份副本是我們進行后續開發的基礎;后面我們將在用戶已經能夠注冊的基礎上進行用戶激活帳號的開發工作,只不過在這個基礎上所開發的一舉一動都會被記錄到email_activation分支中。當用戶注冊成功并能通過郵件激活帳號后,我們就可以將email_activation分支下的工作成果提交且歸并到master主干中,從而把郵件激活的功能和用戶注冊的功能完美的銜接在一起,同時使得項目的版本干凈整潔。
??? 如果我們在email_activation的分支中的開發工作不盡人意,怎么辦呢?如果是一些小小的修改,那非常好辦,直接改成你想要的就是了;可如果是大范圍地修改后,結果卻不是你想要的,有時會萌發重做的想法。下面就來告訴你一些開倒車的技巧:
??? 如果新增了文件,需要先用git add添加(這會被編入git的index,但不會提交到git倉庫),否則回滾后會遺留下來(這句話好像就是說,等到你重新開發的時候發現要編碼的文件已經存在了)。可以用 git status 命令查看都添加或者修改了哪些文件。
??? 如果你當前的工作目錄(working tree)已經混亂不堪,但是還沒有提交,可以使用:
????$ git reset --hard
??? 這會丟棄所有的改變,包括去除已經加到git index里邊的內容;然后將 working tree 和 index 恢復到上次commit時的狀態。
??? 如果想回滾到一個指定的版本,就需要指定版本號:
????$ git reset --hard v1
??? v1 是我們在之前標記過的別名,即上次commit所生產的版本號別名,也可以替換成commit后的版本號,比如 af2d45c... ,版本號是一個唯一的哈希值,每次commit都會生成一個,省去了你找不到版本號的尷尬;基本上,使用git log 命令都能看到版本號。指定版本號的時候不需要寫上所有字符,取前5個就可以,反正能說明版本號是唯一的就行了。比如你只有兩次提交記錄,指定版本號的時候取哈希值的前兩個字符又何嘗不可呢?
??? 還有,記得 --hard 選項要慎重使用,具體的您可以使用 “git reset -h” 命令查閱更多關于撤銷修改的詳細信息。
??? 如果只是想放棄對某一文件的修改,可以使用 checkout 命令。這個命令不單用于分支間的切換,還可以回滾一個指定的文件內容到上次所做的修改,例如:
????$ git checkout app/models/user.rb
??? 這會放棄對user.rb所做的修改,并將user.rb的內容從上一個已提交的版本中更新回來。當然還可以指定回滾到指定版本,例如:
????$ git checkout v1 app/models/user.rb
??? 這會將user.rb的內容從已提交的v1所對應的版本中更新回來。
??? 好了,到此您已經了解了一些實用的GIT知識;是時候步入正題進行我們的開發工作了,我們來了解下工作內容。
###?郵件激活功能?###
??? 1. 用戶成功注冊成為網站用戶;
??? 2. 系統發送一封包含激活鏈接的郵件到用戶注冊時填寫的郵箱中;
??? 3. 用戶點擊郵箱中的激活鏈來接激活帳號;
??? 4. 用戶帳號激活成功,并給出帳號激活成功的提示消息。
??? 根據上面的功能需求,我們在前面兩個故事的基礎上再添兩筆。
### 故事用例之用戶通過郵件激活帳號 ###
????$ gedit features/user_signup.feature
??? 修改后的文件內容如下,
??? 功能: 注冊成為網站會員
????? 為了能夠瀏覽網站只對在線會員可見的那些內容
????? 作為一名訪客
????? 我希望注冊成為網站會員
????? 場景: 用戶填寫無效數據并注冊
??????? 當 我來到用戶注冊頁面
??????? 而且 我在輸入框<用戶名>中輸入<invalid username>
??????? 而且 我在輸入框<電子郵箱>中輸入<invalid email>
??????? 而且 我在輸入框<密碼>中輸入<password>
??????? 而且 我在輸入框<確認密碼>中輸入<verify password>
??????? 而且 我按下<注冊>按鈕
??????? 那么 我應該看到<注冊失敗>的提示信息
????????
????? 場景: 用戶填寫正確的數據并注冊
??????? 當 我來到用戶注冊頁面
??????? 而且 我在輸入框<用戶名>中輸入<404>
??????? 而且 我在輸入框<電子郵箱>中輸入<xuliicom@gmail.com>
??????? 而且 我在輸入框<密碼>中輸入<password>
??????? 而且 我在輸入框<確認密碼>中輸入<password>
??????? 而且 我按下<注冊>按鈕
??????? 那么 我應該看到<注冊成功>的提示信息
??????? 而且 應該有封激活帳號的郵件發送至<xuliicom@gmail.com>
????? 場景: 用戶激活帳號
??????? 假如 我已經使用<404/xuliicom@gmail.com/password>注冊過
??????? 當 我訪問<xuliicom@gmail.com>郵件中激活帳號的鏈接
??????? 那么 我應該看到<帳號激活成功>的提示信息
??? 我們只是在已有的故事上加了個別子句。為了能讓故事跑起來,我們還需要針對故事場景中的情節編寫相應的測試代碼。
### 編寫用于驅動故事運行的測試代碼 ###
????$ gedit features/step_definitions/user_steps.rb
??? 添加如下代碼,
??? Then /^應該有封激活帳號的郵件發送至<(.+)>$/ do |email|
????? user = User.find_by_email(email)
????? user.activation_token.should_not be_blank
????? sent = ActionMailer::Base.deliveries.last
????? sent.to.should eql([user.email])
????? sent.subject.should =~ /激活/
????? sent.body.should =~ /#{user.activation_token}/
??? end
??? Given /^我已經使用<(.*)\/(.*)\/(.*)>注冊過$/ do |username, email, password|
????? @valid_attributes = {
??????? :username????????????? => username,?
??????? :email???????????????? => email,?
??????? :password????????????? => password,?
??????? :password_confirmation => password
????? }
????? @user = User.create!(@valid_attributes)
??? end
??? When /^我訪問<(.*)>郵件中激活帳號的鏈接$/ do |email|
????? user = User.find_by_email(email)
????? visit activate_url(:token => user.activation_token)
??? end
??? 故事用例基本上涵蓋了我們開發的用意,測試代碼準備就緒,還等什么,趕緊跑起來看看吖。
??? 運行測試,
????$ ruby script/cucumber -l zh-CN features/user_signup.feature
????
??? 測試未能通過,原本應該有封激活帳號的郵件發送至<xuliicom@gmail.com>,然而卻沒有,因為我們還沒有編寫用于發送激活郵件的代碼。習慣了玩測試的話,測試結果無疑對指導你的編碼工作非常有幫助!
??? 接下來,我們就來做這些工作。
### 添加激活碼字段 ###
??? 怎么知道用戶有沒有激活帳號呢?答案是在 users 表中增加用于標識用戶帳號是否激活的兩個字段,一個用來存放激活碼,另一個用來記錄帳號激活時間。假設這兩個字段分別是 activation_token 和 activated_at,如果 users.activation_token 字段有值,那么就說明用戶還沒有激活,如果 users.activation_token 為空且 users.activated_at 有值,那么就說明用戶已經激活過了。
??? 下面來添加這組字段,
????$ ruby script/generate migration EmailConfirm
????$ gedit db/migrate/*_email_confirm.rb
??? class EmailConfirm < ActiveRecord::Migration
????? def self.up
??????? add_column :users, :activation_token, :string
??????? add_column :users, :activated_at, :datetime
????? end
????? def self.down
??????? remove_column :users, :activated_at
??????? remove_column :users, :activation_token
????? end
??? end
????$ rake db:migrate
????$ rake db:test:prepare
??? 表結構準備完畢后,再來生成用戶注冊時的激活碼。
### 生成激活碼——activation_token ###
????$ gedit app/models/user.rb
??? before_create :initialize_salt, :encrypt_password, :initialize_activation_token
??? # 生成并返回標識碼
??? def generate_token
????? encrypt(Time.now.to_s.split(//).sort_by {rand}.join)
??? end
??? # 生成激活碼
??? def initialize_activation_token
????? if new_record?
??????? self.activation_token = generate_token
????? end
??? end
??? 數據模型搞定后,再從路由下手,需要指定控制器該如何分配響應請求。
### 配置激活帳號的路由——activate_url ###
????$ gedit config/routes.rb
??? 修改后routes.rb文件內容如下,
??? ActionController::Routing::Routes.draw do |map|
????? map.with_options :controller => 'users' do |page|
??????? page.signup '/signup', :action => 'new'
??????? page.activate '/activate/:token', :action => 'activate'
????? end
????? map.resources :users
??? end
??? 此時,如果你不清楚接下來要做什么;不妨運行測試,測試結果會告訴你答案。由于筆者知道會失敗也知曉接下里該做什么,所以就略過此步;因為Model和Route都準備完畢,是時候動手編寫業務流程了。
??? 如果你用Rails發過郵件,下面的步驟你一定很熟悉。
### 生成郵件 ###
????$ ruby script/generate mailer UserMailer confirm
????$ gedit app/models/user_mailer.rb
??? class UserMailer < ActionMailer::Base
??????
????? def confirm(user, sent_at = Time.now)
??????? subject??? '請激活您的帳號'
??????? recipients user.email
??????? from?????? 'Admin'
??????? sent_on??? sent_at
????????
??????? body?????? :username => user.username,?
?????????????????? :url? => activate_url(:token => user.activation_token)
????? end
??? end
????$ gedit app/views/user_mailer/confirm.erb
??? 親愛的 <%=@username%>:
??????? 您的帳號已經創建成功,請點擊下面的鏈接激活您的帳號:
??????? <%=link_to @url, @url%>
### 發送郵件 ###
??? 用戶注冊成功之后,需要發送一封確認郵件到用戶注冊時填寫的電子郵箱中。雖然可以在 User 模型中添加 after_create 的一個回調代碼來執行,但這樣就給 User 模型類增添了本不應該承擔的責任;我們只需要 User 模型提供數據,而不是將發送郵件的任務丟給它。這時候 ActiveRecord 提供的 Observer 就可以派上用場了,使用Observer的好處是它可以將自身連接到模型類中并注冊為回調,卻無需修改任務模型類的代碼,我們將其稱之為觀察器(是否聯想到Ruby設計模式中的觀察者模式,呵呵)。下面,我們針對 User 模型創建一個觀察器:
????$ ruby script/generate observer User
????$ gedit app/models/user_observer.rb
??? class UserObserver < ActiveRecord::Observer
????? def after_create(user)
??????? UserMailer.deliver_confirm(user)
????? end
??? end
??? 然后在 config/environment.rb 注冊這個 Observer。
????$ gedit config/environment.rb
????config.active_record.observers = :user_observer
??? 再次發動測試引擎,看看是否working,
????$ ruby script/cucumber -l zh-CN features/user_signup.feature
????
??? 由于在生成郵件那一章節里,激活鏈接我們用的是 link_url 這種形式,如果你知道 link_url 和 link_path 的區別,那么根據上面的測試結果,你應該了解出錯的原因。如果不了解,筆者在這里補充下,link_url 會在鏈接中加上協議名、主機名和端口號這些;而 link_path 則不用,它會直接用根目錄“/”代替之;也就是說, link_url 會在鏈接中加上網址;又或者說,link_url 采用絕對路徑,而 link_path 采用相對路徑。
??? 考慮到現實中的用戶注冊,系統會發送一封包含網址的郵件到注冊用戶的郵箱中,我們之前的郵件模板里不得不采用 link_url 這種形式。結合測試結果來看,也許此時您已經意識到,我們是不是忘了配置主機名呢?
??? 恭喜您!您確實猜對了。
### 配置郵件中激活鏈接的絕對路徑 ###
????$ gedit app/models/user_mailer.rb
????default_url_options[:host] = HOST
??? 在 config/environments/test.rb 和 config/environments/development.rb 這兩個配置文件中定義 HOST 常量,為了開發和測試需要,這里設置成localhost就可以了。
????HOST = 'localhost:3000'
??? 不過在 config/environments/production.rb 中,HOST 常量的值就必須是真實的主機名了。
??? 另一種方法無需修改app/models/user_mailer.rb和定義HOST常量,直接在各environment/各文件或environment.rb中配置就行了,如下代碼
????$ gedit config/environment.rb
????config.action_mailer.default_url_options = { :host => 'localhost:3000' }
??? 這樣做的好處是只需修改一處。
??? 好了,補上這個配置,再運行測試,看看有什么不同。
????$ ruby script/cucumber -l zh-CN features/user_signup.feature
????
### 激活帳號 ###
??? 看來我們的郵件能夠成功發送了,不過好像訪問郵件中的確認鏈接時出了點問題,根據調試信息“ActionController::UnknownAction”顯示,應該是沒有找到激活帳號的具體行為(action)。在前面的開發中,我們真的就還沒有編寫響應用戶激活帳號的相關代碼,想必此時我們都清楚該做哪些工作了。
??? 我們需要給 UserController 類添加一個 Action 來響應用戶激活帳號的請求。
????$ gedit app/controllers/users_controller.rb
??? 之前我們在config/routes.rb文件中定義了activate_path,且該activate_path 的 :action 參數指向 activate 方法;于是乎,activate 就是我們需要在 UserController 類中添加的 action。activate方法的代碼如下:
??? def activate
????? if @user = User.find_by_activation_token(params[:token])
??????? if !@user.activated?
????????? @user.email_confirm!
????????? flash.now[:notice] = '恭喜您,帳號激活成功!'
??????? end
????? end
??? end
??? 仔細觀察 UserController#activate,我們還需要在 User 模型中編寫 activated? 和 email_confirm! 這兩個實例方法,前者用來確認用戶的帳號是否已經激活過,后者則用來激活用戶的帳號。
????$ gedit app/models/user.rb
??? 在 protected 之前添加如下兩個方法:
??? # 檢查是否已經激活
??? def activated?
????? # 當 activation_token 為 nil 時表示用戶帳號已經激活
????? activation_token.nil?
??? end
??????
??? # 激活帳號
??? def email_confirm!
????? update_attributes(:activation_token => nil, :activated_at => Time.now)
??? end
??? 運行測試看看,
????$ ruby script/cucumber -l zh-CN features/user_signup.feature
????
??? 看來是沒有找到模板文件,在此補上用戶成功激活帳號的頁面。
????$ gedit app/views/users/activate.html.erb
??? 保存即可。運行測試:
????$ ruby script/cucumber -l zh-CN features/user_signup.feature
??? OK,測試通過!如圖,
????
### 親臨現場 ###
??? 最后開發人員自己別忘了手工測試,以確保萬無一失。
??? 先清除數據庫中的記錄,
????$ ruby script/console
????>> User.delete_all
??? 假設我們以404為用戶名成功注冊后,我們來看看數據庫中404的activation_token字段是否有值。
????>> User.find_by_username('404', :select => "username, activation_token, activated_at")
????
??? 可以看到,activation_token 的值是一串加密后的字符,activated_at值為空,這說明程序已經給注冊用戶生成了激活碼,而且此時用戶還沒有激活帳號。
??? 當我們注冊成功后,打開郵箱卻并沒有看到激活帳號的郵件,這是怎么回事呢?
??? 因為測試程序跑到是test環境,而我們手工測試的時候,程序是運行在development環境下的,我們沒有針對development環境配置郵件服務器。下面我們采用SMTP的發信方式,這里的SMTP SERVER用的是GMAIL,而且是SSL驗證登錄方式;三次握手,發信速度沒sendmail那么快,呵呵!
????$ gedit config/environment.rb
??? config.action_mailer.delivery_method = :smtp
??? config.action_mailer.default_charset = 'utf-8'
??? config.action_mailer.smtp_settings = {
????? :address????????????? => 'smtp.gmail.com',
????? :port???????????????? => 25,
????? :domain?????????????? => 'YOUR_DOMAIN',
????? :user_name??????????? => 'YOUR_GMAL_USERNAME',
????? :password???????????? => 'YOUR_GMAIL_PASSWORD',
????? :authentication?????? => 'login',
????? :enable_starttls_auto => true
??? }
??? 該配置中大寫部分自行替換即可。
??? 清空users表,我們重新注冊404這個用戶。
????$ ruby script/console
????>> User.delete_all
??? 然后去郵箱看看,
????
??? 這回我們打開郵箱看到了激活帳號的郵件信息,不過郵件內容中的鏈接標簽沒有生效,我們期望發送到用戶郵箱的是HTML格式的郵件。ActionMailer可以讓我們發送多種格式的郵件,只需要按相應的內容類型修改郵件模板的文件名格式即可。基本上,郵件模板的文件名的格式像這樣:name[.content.type].renderer;content.type 可選,缺省情況下為文本格式,你也可以手工指定為 text.plain,要發送HTML格式的郵件就需要指定為 text.html;文件后綴 renderer 一般情況下都是 erb(如果你用了HAML插件,模板后綴名應該是haml)。下面我們將之前文本格式的郵件模板修改為網頁形式的:
????$ mv app/views/user_mailer/confirm.erb app/views/user_mailer/confirm.text.html.erb
??? 再次清空users表,重新注冊404這個用戶,然后前往郵箱看看我們收到的郵件是否是網頁格式的。
????
??? 我們看到激活帳號的超鏈接生效了(沒有將超鏈接標簽明文顯示),這說明系統發送出去的確實是HTML郵件。
??? 接下來我們點擊郵件中的鏈接來到了激活帳號的頁面,我們看到帳號激活成功的提示信息。
????
??? 如果激活成功,數據庫中的activation_token字段應該是空值,且activated_at字段的值應該為一時間戳;在之前的程序中,我們確實是按此邏輯編碼的。雖然測試成功,而且我們也非常順利地親歷了一遍注冊流程,那么是否就說明我們的應用程序沒有程序上的漏洞了嗎?我們真的激活帳號了嗎?我們不妨看看數據庫這只黑匣子,此時應該是讓數據說話的時候了。
????$ ruby script/console
????>> User.find_by_username('404', :select => "username, activation_token, activated_at")
????
??? 哎呀!記錄居然沒被更新,看來我們被表面現象給忽悠了。我想你此時也和我一樣迷惑,為什么數據記錄沒有被更新呢?這中間到底發生了什么?這讓我不由自主地想象起來,也許Rails的ORM真的修改了User實例對象的activation_token和activated_at屬性的值,只不過還沒有成功地寫入到數據庫里邊而已。果真如此嗎?如何證明這一說法成立呢?我們來看看User模型類的 email_confirm! 方法,下面是email_confirm! 方法的源碼:
??? # 激活帳號
??? def email_confirm!
????? update_attributes(:activation_token => nil, :activated_at => Time.now)
??? end
??? 我們知道,update_attributes 方法還有一個和自己長得差不多一樣的方法,即 update_attributes!
;后者比前者僅僅多一個感嘆號而已,兩者都是更新當前模型對象所指向的數據記錄,只不過前者更新失敗會返回false,后者更新失敗則會拋出異常信息并停止程序運行,我們不妨用 update_attributes! 替換 email_confirm!方法中的update_attributes,如果問題真的出現在這里,至少我們也可以看見拋出的錯誤信息,這些錯誤調試信息對開發人員來說是那么的重要。
????$ gedit app/models/user.rb
??? 修改 email_confirm! 方法如下:
??? def email_confirm!
????? update_attributes!(:activation_token => nil, :activated_at => Time.now)
??? end
??? 保存,然后重新訪問或刷新激活帳號的頁面,我們看到系統捕獲到了非常實用的情報,如圖:
????
??? 看來問題還真的出在User模型類的email_confirm!方法這里,當程序嘗試更新 activation_token 和 activated_at 這兩個字段時,系統告訴我們密碼不能為空并就此打住,程序拋出錯誤并停止執行,后面當然不會更新數據庫里邊的記錄了。找到出錯的原因后,我們馬上就明白 update_attributes(或update_attributes!) 會更新當前對象所指向的記錄的所有字段,并在更新之前執行數據校驗,如果校驗失敗就會打斷程序的運行。想到此,針對問題的解決方案也初現輪廓,只要程序更新指定的字段,并在更新這些指定字段的時候不去校驗其他字段的數據有效性就行了。OK,我們有非常適合用于email_confirm!的替代寫法,不妨修改email_confirm!方法如下:
????$ gedit app/models/user.rb
??? # 激活帳號
??? def email_confirm!
????? self.activation_token = nil
????? self.activated_at = Time.now
????? save(false)
??? end
??? 上述代碼中的 save 方法會更新這些字段的值,第一個參數的值指明為false后將不會執行數據校驗,看來這一切和我們的想法非常吻合,不妨保存user.rb再刷新幾次瀏覽器看看。第一次刷新和我們初次訪問激活鏈接看到的效果一樣,都是提示帳號激活成功,后面幾次就看不到激活成功的消息了,因為帳號只需要激活成功一次就足夠了,效果確實很理想,我們去訪問下數據庫讓它給我們做個見證。
????$ ruby script/console
????>> User.find_by_username('404', :select => "username, activation_token, activated_at")
????
??? 哈哈,數據記錄已經更新了,這意味著程序已經可以按照我們之前的意愿運行了。用戶提交注冊資料后會收到一封關于激活帳號的郵件,然后點擊其中的鏈接可以成功激活他的帳號。
??? 至此,我們在 email_activation 分支上的開發工作已經順利完成,可以將工作成果歸并到主干中去了。
### 提交工作成果到GIT倉庫 ###
??? $ git add .
??? $ git commit -m?"People can activation their accounts by the confirm emails."
??? $ git checkout master
??? $ git merge email_activation
??? $ git branch -d email_activation
??? $ git tag v2
??? (注意,真正的開發中可不是到功能開發完畢了才commit,而是邊開發邊add和commit。為了方便演示編碼過程,文章中沒有一一列舉。)
### 小結 ###
??? 在這篇教程中,我們的開發工作遇到了不小的挫折,尤其是在人工測試那里,經過我們自己動手測試后,才知曉我們的程序漏洞百出。之所以這樣,是由于筆者有意而為之,其實筆者的用意非常簡單,就是想告訴開發者親臨現場做人工測試的重要性。也許確實讓您受挫了,覺得好像是為了測試而測試似的;大可不必有如此想法,如果您是位Rails熟手,想必也不會犯那些低級錯誤,比如update_attributes和save(false)這種區別及其應用場合,也會知曉 test/development/production 這幾種環境的區別;那也就避免了些不必要的麻煩。經驗是慢慢積累的,過程可以幫我們汲取經驗。等您自己應用熟練了,我相信您能體會到測試帶來的好處。
### 下節預告 ###
??? 接下來我們依然是借助cucumber+rspec來驅動用戶登錄功能的開發,看測試跟session和cookie打交道。如果有興趣,期待您能夠下次光臨!如果有好的建議和經驗非常希望能夠與您交流,您可以在下面發表留言或者和我email聯系,我的郵箱是 xuliicom@gmail.com。
標簽:?Cucumber,?Rails,?Rspec,?TDD
Posted by 404轉載于:https://www.cnblogs.com/ToDoToTry/archive/2011/09/10/2173390.html
總結
以上是生活随笔為你收集整理的使用Cucumber+Rspec玩转BDD(2)——邮件激活的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 域名解析文件hosts文件是什么?如何修
- 下一篇: 大数据决策支持的优势