TDD 有助于理清思路蓝牲。實(shí)踐 TDD 的步驟如下:
- 明確功能
- 驗(yàn)證功能(寫測試)
- 實(shí)現(xiàn)功能
- 運(yùn)行測試
- 修改功能 (非必須)
其中第一步是理清思路,在紙上寫寫畫畫泰讽,細(xì)分功能例衍,不需要寫代碼昔期。大多程序員不管三七二十一,想到什么就寫什么肄渗,盡快上手寫代碼镇眷,出現(xiàn)問題了再修補(bǔ),思路不清晰翎嫡。其實(shí)這一步才是最重要的欠动。
拿修改密碼功能舉例,例子中使用后端語言為 Ruby惑申,Web 框架是 RoR具伍,測試框架 Rspec。不了解該語言可以把代碼當(dāng)偽代碼看,畢竟 Ruby 很接近自然語言 :)
明確功能:
該功能的效果:用戶修改密碼后,密碼會(huì)變(廢話)遗嗽,需要使用新密碼登錄荐类。
實(shí)現(xiàn)方法如下:
驗(yàn)證舊密碼與現(xiàn)在的密碼是否一致 => 修改密碼,該功能比較簡單入录。驗(yàn)證功能(寫測試):
創(chuàng)建用戶 => 調(diào)用修改密碼接口 => 檢驗(yàn)密碼是否改為新密碼
# spec/controllers/api/users_controller_spec.rb
RSpec.describe Api::UsersController type: :controller do
describe '#change_password' do
old_pwd = 'adfslkj'
new_pwd = '87234sd'
user = create(:user, password: old_pwd)
session[:user_id] = user.id # 通過會(huì)話標(biāo)記登錄狀態(tài)
post(:change_password, params: { old_pwd: old_pwd, new_pwd: new_pwd, confirmed_pwd: new_pwd } )
expect(response.status).to eq(200) # 檢驗(yàn)是否返回成功的響應(yīng)
user.reload # 成功調(diào)用接口后,密碼應(yīng)該變了,重新從數(shù)據(jù)庫獲取用戶
expect(user.valid_password?(old_pwd)).not_to be_truthy # 舊密碼失效
expect(user.valid_password?(new_pwd)).to be_truthy # 判斷傳到接口的新密碼現(xiàn)在是否為有效的密碼
end
end
現(xiàn)在運(yùn)行測試惕味,還沒寫功能,測試肯定不通過玉锌。
$ rspec spec/controllers/api/users_controller_spec.rb
# 失敗
- 實(shí)現(xiàn)功能:
實(shí)現(xiàn)方法主要如步驟 1 所說名挥。
驗(yàn)證舊密碼與現(xiàn)在的密碼是否一致 => 修改密碼
# app/controllers/api/users_controller.rb
...
def change_password
old_pwd, new_pwd, confirmed_pwd = require_params!(:old_pwd, :new_pwd, :confirm_pwd)
if !current_user.valid_password?(old_pwd)
return fail_res(400, '無效的舊密碼')
end
current_user.update!(password: new_pwd) # 修改密碼
res(200, '修改成功')
end
...
看吧,很簡單主守,幾行代碼就搞定禀倔。不過有些異常情況沒處理,我們稍后再講参淫。
- 運(yùn)行測試救湖、修改功能:
接下來運(yùn)行測試
$ rspec spec/controllers/api/users_controller_spec.rb
# 通過.
測試通過啦。然后我們還要改進(jìn)一下代碼涎才,確認(rèn)新密碼和確認(rèn)密碼是否一致捎谨。
...
def change_password
old_pwd, new_pwd, confirmed_pwd = require_params!(:old_pwd, :new_pwd, :confirm_pwd)
if !current_user.valid_password?(old_pwd)
return fail_res(400, '無效的舊密碼')
end
if new_pwd != confirmed_pwd
return fail_res(400, '新密碼與確認(rèn)密碼不一致')
end
current_user.update!(password: new_pwd) # 修改密碼
res(200, '修改成功')
end
...
寫好測試后,以后就可以放心修改這個(gè)接口憔维,或者是重構(gòu)跟用戶密碼有關(guān)的代碼涛救。只要重構(gòu)后可以通過測試,就比較可靠了业扒。
要是遇到?jīng)]想到的異常情況检吆,再補(bǔ)多一個(gè)測試就好了。