jollen.org

Jollen 的 Blog
Jollen's email: jollen # jollen.org
more:  Jollen's Training

農場計畫 Week #1:Behavior-Driven Development

.作者:jollen/
.日期:November 19, 2014 4:13 PM


本文章採用 Markdown 語法撰寫(why?),若無法閱讀內文,請點擊這裡

Abstract

Behavior-Driven Development(BDD)是以故事情節做為基礎,因此 BDD 的核心在 user story。從 user story 來發展 software prototype 的過程可以單純是 coding,並且使用開發者界的手法「code is document」,來讓代碼與文件合而為一。Code is document 的關鍵,首先取決於二個層面:

  • 代碼品質(code quality)
  • 專案管理(Git)

現在是一個軟體開發的先進時代,只要代碼品質夠好,它就是一份文件,所以你不必要另外花時間,就只是為了寫 Documentation。好的開發者,閱讀 code is document 的效率,是讀傳統文字文件的數十倍。

有了 code is document 的觀念,就可以明白為什麼在完成一個 user story 後,就可以直接撰寫程式碼、製作第一個 Prototype。這是又直接、又有效率的做法:user story -> prototype。

要測試這個 prototype,可以想辦法將 user story 直接轉化(code generation)為測試步驟(step definitions)。以上介紹的 user story 與 step definitions,可以透過一些 BDD framework 工具來實現。

cucumber 是目前很受歡迎的 BDD framework,它採用 Gherkin 語法來撰寫 user story,並且將 user story 編譯為 step definitions 的 code stub(程式碼骨架)。

User Story

用「故事情節」的方式,來表達、描述與表現你的功能(features),而不是用規格(spec)的方式。如果你想知道什麼叫「規格描述」,台灣 ODM / OEM 廠裡,應該隨地都可以撿到這種文件。

這個部份,BDD 用到很多方式跟軟體工具,不過從 Startup 的角度來看,其實一開始採用 story board 的方式,再搭配一段 story template 就夠了。一份典型的 story template 如下:

In Order To <biz value is derived>
As a <role>
I want <some feature> 

從這個 template 的句型來看,story 的敍述應該是「value first」,而不是 function first。一份簡單的 user story 可以極簡到使用「記事本」來撰寫,不過,為了易於管理,選用一個適合的 BDD 寫作架構還是有必要的。

Cucumber and Gherkin

Cucumber1 是目前頗受歡迎的寫作框架,它原本是為 Ruby 語言所打造,不過現在也有 JavaScript 的版本:cucumber-js2 。Cucumber 採用 Gherkin 語法來描述 user story。Gherkin 語法所描敍出來的文件結構稱為 'Give-When-Then[3]',這裡有一個簡單的例子:

 1 #
 2 # features/unsplash.feature
 3 #
 4 
 5 Feature: Unsplash feature
 6   As a traveler of photographer
 7   I want to post photos on website
 8   So that I can share with my excitings
 9 
10   Scenario: Post photo
11     Given User login
12     Given Use Facebook account
13     When Interact with upload element
14     Then You see the photo

以 user story 來表示 spec 是 BDD 的核心精神。同樣地,你可以用記事本、用自已的語意來撰寫 user story,然後用瀏覽器,以及「工人瀏覽」方式來測試。但有一個 BDD 框架,還是最省時省力的。

Cucumber-js 就提供了這樣的測試框架。要測試你的 features,要再加入二個東西:

  • Support files
  • Step definitions

Support files 要定義一個 World 類別,裡面要實作 visit method。Step definitions 就是測試 user story 的步驟,這個部份的程式碼骨架,可以透過 cucumber-js 來產生。

以下是 support files 與 step definitions 的例子,下一個階段再說明程式碼實作細節。

Support Files

 1 // test/features/support/world.js
 2 
 3 module.exports = function() {
 4   var zombie = require('zombie')
 5     , HTML5  = require('html5');
 6 
 7   this.World = function World(callback) {
 8     this.browser = new zombie.Browser(/* {runScripts:true, debug:false, htmlParser:  HTML5} 
 9 */);
10 
11     this.page = function(path) {
12      return "http://localhost:3000" + path;
13     };
14 
15     this.visit = function(path, callback){
16       this.browser.visit( this.page(path), function(err, browser, status) {
17         callback(err, browser, status);
18       });
19     };
20 
21     callback(); // tell Cucumber we're finished and to use 'this' as the world instance
22   };
23 };

Step Definitions

 1 // test/features/support/world.js
 2 'use strict';
 3 
 4 module.exports = function() {
 5   var zombie = require('zombie')
 6     , HTML5  = require('html5');
 7 
 8   this.World = function World(callback) {
 9     this.browser = new zombie.Browser(/* {runScripts:true, debug:false, htmlParser: HTML5} 
10 */);
11 
12     this.page = function(path) {
13      return "http://localhost:3000" + path;
14     };
15 
16     this.visit = function(path, callback){
17       this.browser.visit( this.page(path), function(err, browser, status) {
18         callback(err, browser, status);
19       });
20     };
21 
22     callback(); // tell Cucumber we're finished and to use 'this' as the world instance
23   };
24 };

實作

實作的方式當然是使用 HTML5 技術,也就是 HTML5/CSS/JS。從能力上來看,Full Stack Web Development 的技能是必備的。雖然 Full Stack Web Developer 的工作看似包山包海,要學習的主題也很廣泛,但有架構思維,也有主軸的話,其實學習可以很有效率;否則,學習再多,都是「碎片化」的學習方法,感覺學到或看過的東西很多,但每一種都只有「Hello World」等級。

這裡提到的架構思維就是 Single-Page Application - SPA。

Feature: Unsplash Story

一份 .feature 檔描敍一個 user story。底下是一個例子,故事的主題叫做「Unsplash」。

 1 #
 2 # test/features/unsplash.feature
 3 #
 4 
 5 Feature: Unsplash feature
 6   In order to share my enjoys
 7   As a traveler of photographer
 8   I want to post photos on website
 9 
10   Scenario: Post photo
11     Given User login
12     When Interact with upload element
13     Then I should see "my photo"
14 
15   Scenario: Slideshow
16     Given The latest photo gallery
17     When Tap to next photo
18     Then I see one photo
19       And Full page

第 5 行的「Feature:」是 Gherkin 的語法,說明故事標題。標題底下的縮排區段,是故事敍述,請使用先前介紹的 user template 句型,來寫故事:In order to ... As a ... I want ...。

緊接著用「Scenario:」語法,來定義「功能」。Scenario 的寫法是使用「Given-When-Then」句型:

  • Given:系統的狀態,例如:User login,表示系列要處在登入狀態
  • When:使用者的動作,例如:Interact with upload element,表示使用者與上傳介面互動
  • Then:outcomes,也就是輸出。例如:I should see "my photo",表示畫面顯示使用者上傳的照片

一個 user story 可以包含數個 scenario,也就是多個功能。除此,Gherkin 也有「And, But」語法,例如第 18-19 行。Unsplash story 的 prototype:

http://innoboard.cc/unsplash

Feature: Slidenow Story

設計一個使用 Markdown 語法的簡報服務,力求極簡易用。

 1 #
 2 # test/features/slidenow.feature
 3 #
 4 
 5 Feature: Slidenow feature
 6   In order to lively introduce something
 7   As a coder, developer and instructor
 8   I want to make slides in Markdown
 9 
10   Scenario: Read slides
11     Given Landing page showing slides items
12     When Click the slide item
13     Then I should see full screen "slide"
14 
15   Scenario: Submit a slide
16     Given The submit page
17       And User login
18     When Commit markdown document
19     Then I send a new slide
20       And Use CC4.0 license

Prototype 實作:

http://booklog.io

特別說明:Solution Storyboard vs User Story

Solution Storyboard(或簡稱 Story Board)是 101 Design Methods 的一個流程,一般是採用漫畫的方式呈現。這是非常有幫助的設計思考方法,細節請看 Leon 老師的摘要文件;以及 101 Design Methods 的 Model 6.7。

Story board 的範例說明裡,將 Mokoversity Farm 的思考,製作成簡報後,再實作為 landing page。但是請注意,這個 landing page 呈現的是一份「簡報」;但 user story 要實作的是 Prototype(App)。

Leon 老師在 hackpad 有一份 story board 說明,這個例子先將想法做成簡報(Presentation),再將簡報內容實作為 landing page。請注意,這份 landing page 是 idea 的「簡報」,而不是 idea 的實作。

同時也要注意,BDD 的 user story 屬於軟體工程的一環,它的目標是書寫 Scenario(也就是軟體功能),然後實作 prototype;BDD 不是用來製作 business plan 簡報的方法論,所以不能把 BDD 的 user story 跟 Design Thinking 或 Lean Startup 畫上等號。實際上,BDD 的 user story 是屬於數學上的 finite state machine(FSM)。

BDD 的 User story 要達到的目的是實作,也就是想法的實作;即 Prototype。

關於 Mokoversity 農場計畫

Mokoversity 農場計畫(Farm Team)是一個 Pre-Startup 的訓練場(Play Ground)。在農場裡可以學習 Coding、打造 Prototype 與建構 Entrepreneur Mindset,這裡更是一個 Entrepreneur 黃金圏(Golden Circle)。更多資訊,請訪問:https://www.mokoversity.com/farm/zh-tw

References

[3]: Given When Then, https://github.com/cucumber/cucumber/wiki/Given-When-Then

[4]: BDD in JavaScript: CucumberJS, http://custardbelly.com/blog/blog-posts/2014/01/08/bdd-in-js-cucumberjs/

Tags:

純手工打造說明:技術專欄文章為 Jollen 原創,內容皆為人工撰寫,無 AI 生成。轉載請註明出處與作者,並全文引用。轉載時請在文章開頭或結尾明顯處註明「本文出處:https://www.jollen.org,已取得原作者同意並授權使用。」
訂閱電子報:不定期 Jollen's Blog 精選文章隨 Moko365 電子報寄送;請透過 Moko365 電子報訂閱(可隨時取消)。

Copyright(c) 2001–2014 www.jollen.org. All rights reserved.
Last update: 2026-07-22