使用 cucumber 編寫用戶故事

cucumber 是一款 BDD 的工具,通常用于集成測(cè)試。
如果應(yīng)用是一個(gè)只提供 API 給手機(jī)端調(diào)用的后端程序。本來(lái)并不是很適合使用 cucumber。
不過(guò)隨著開(kāi)發(fā)的深入,我越來(lái)越覺(jué)得單純的 API 測(cè)試(controller 層)無(wú)法表達(dá)用戶的意圖。
而目在開(kāi)發(fā)團(tuán)隊(duì)對(duì)產(chǎn)品的用例也不是非常清楚,沒(méi)有文檔可言的情況下,使用 cucumber 來(lái)編寫用例也是一個(gè)不錯(cuò)的選擇。

使用 cucumber 的好處

在開(kāi)發(fā)應(yīng)用時(shí),我們會(huì)把大的功能點(diǎn)分解成小的功能。但是在理解業(yè)務(wù)邏輯時(shí),我們要從更宏觀的角度看待系統(tǒng)。
Rails 框架的單體風(fēng)格并不足以讓人非常舒服的熟悉一個(gè)系統(tǒng)。因?yàn)?ActiveRecord 的特性,我們只能看到模型之間的關(guān)系,而看不到用戶是是如何和它們交互的。
這就像給你一堆齒輪,轉(zhuǎn)軸和馬達(dá)一樣,你知道如何拼裝它們,但你看不到它們所組成的到底是汽車,飛機(jī)還是輪船。
通過(guò)用戶故事,無(wú)論是開(kāi)發(fā)人員還是業(yè)務(wù)人員都能對(duì)系統(tǒng)有一個(gè)快速直觀的理解。
而 cucumber 就是將用戶故事代碼化的一款工具。

Get Started

如果使用 rails 自帶的 minitest 測(cè)試框架。添加 cucumber 的步驟如下。

  1. 在 Gemfile 中添加

    group :test, :development do
      gem 'cucumber-rails', :require => false
      gem 'database_cleaner'
    end
    
  2. 安裝

    bundle install
    rails generate cucumber:install
    
  3. 編寫第一個(gè) feature

    @require_login
    Feature: XiaomiSports
      In order to know about my xiaomi sports
      As a care user with xiaomi profile binding
      I want list of my xiaomi sports
    
    Scenario: List of the xiaomi sports
      Given the system knows my xiaomi profile
      And the system knows about the following sports::
        |  record_on |  step |
        | 2015-05-25 |  8000 |
        | 2015-05-26 | 10000 |
        | 2015-05-27 | 12000 |
      When the client requests GET "/api/v1/xiaomi_profile/exercise_data?fromDate=2015-05-25&toDate=2015-05-27"
      Then response should be "200"
      And the JSON response should be an array with 3 "step" elements
    
  4. 執(zhí)行 bin/rake cucumber 并且實(shí)現(xiàn)相應(yīng)步驟
    cucumber 會(huì)自動(dòng)輸出實(shí)現(xiàn)步驟的提示代碼類似于:

You can implement step definitions for undefined steps with these snippets:
Given(/^the system knows about the processions of my corp$/) do
     pending # express the regexp above with the code you wish you had
end

只要把上述代碼拷貝到 features/step_definitions/xxxx_steps.rb中, 然后填寫測(cè)試代碼, 那么執(zhí)行到這段"情節(jié)"時(shí), 代碼塊中的代碼就會(huì)被執(zhí)行.

tips

一些實(shí)用小技巧

使用 tag 來(lái)實(shí)現(xiàn) AOP 的效果

我在上面的代碼中使用了 @require_login 這個(gè) tag, 表示下面的步驟是需要在用戶登錄狀態(tài)下才能完成的.

可以對(duì) tag 添加鉤子函數(shù)來(lái) DRY,features/support/hooks.rb

Before('@require_login') do
  # login logic
end

table 的使用

在 cucumber 中使用 table 可以非常直觀的表達(dá)一組數(shù)據(jù)結(jié)構(gòu), 比如上面提到的:

|  record_on |  step |
| 2015-05-25 |  8000 |
| 2015-05-26 | 10000 |
| 2015-05-27 | 12000 |

在 step 中可以這樣獲取:

Given(/^the system knows about the following sports::$/) do |table|
    table.hashes #=> [{"record_on"=>"2015-05-25", "step"=>"8000"}, {"record_on"=>"2015-05-26", "step"=>"10000"}, {"record_on"=>"2015-05-27", "step"=>"12000"}]
end

request header 的設(shè)置方式

直接上代碼, 模擬客戶端的請(qǐng)求

  @current_user = FactoryGirl.create(:access_token).user
  header 'Accept', 'application/json'
  header 'Content-Type', 'application/json'
  header 'Token', @current_user.access_tokens.last.token

參考文檔

https://cucumber.io/docs/reference/rails
http://anthonyeden.com/2013/07/10/testing-rest-apis-with-cucumber-and-rack.html
http://www.emilsoman.com/blog/2013/05/18/building-a-tested/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,940評(píng)論 0 23
  • 柏邦妮是我欣賞的奇葩辯手,也是一枚可愛(ài)的女編劇。幾個(gè)月前,她在微博里分享了一本書,來(lái)自美國(guó)作家伊萊恩·阿倫《天生敏...
    了了君閱讀 2,669評(píng)論 98 121
  • 網(wǎng)站 http://www.qplot.cn:3838/apps/007-16S_OTUtax/ 這是一個(gè)整合多個(gè)...
    quan575閱讀 2,985評(píng)論 8 2
  • --------得不到那個(gè)人,每天還會(huì)想他,睜開(kāi)眼睛,閉上眼睛,發(fā)呆,瞎想都是他,怎么辦? ---------就這...
    藍(lán)湛的湛閱讀 153評(píng)論 0 0
  • 其實(shí)自己也不知道想要說(shuō)什么,可又有些感觸想記錄,所以就在此刻寫下了這篇碎碎念。 自己的興趣一直都是舞蹈和攝影...
    jussica閱讀 210評(píng)論 0 0