l

2017年4月28日 星期五

C.C. Agile 56心得

April 28 15:55~16:49

屏幕截图 2017-04-28 15.23.28

 

昨天是C. C. Agile 第56次聚會,邀請服務於NEXCOM公司的Cobalt Chang分享Software Driven Hardware Development這個題目,談談敏捷開發如何應用於嵌入式系統開發中。

第一次認識Cobalt是在去年(2016)某一次C. C. Agile聚會,當時採用open space(開放空間)的形式討論敏捷開發的問題。Cobalt與他的主管和同事一起參加,Teddy剛好參與他們的討論小組,當下聽到了他們所遭遇到的許多問題,也聽到與會者給他們許多不錯的建議。

本以為活動結束就結束了,沒想到之後每個月Cobalt他們都來參加C. C. Agile聚會,在一次聊天當中Cobalt提到他們落實了幾項當初在open space活動中所聽到的建議之後,解決了不少團隊的問題。當下Teddy覺得很意外,因為說實話大部分的人參加活動聽到建議都只是「聽聽而已」,回去公司之後並不會採取什麼改善行動。沒想到Cobalt他們不但行動,而且還有不錯的改善成效,所以Erica和Teddy便邀請他們來C. C. Agile分享。更難得的是,Cobalt他們的產品是屬於軟硬整合的產業,在與硬體相關的產業落實敏捷開發相較於純軟體產業更加困難

屏幕截图 2017-04-28 16.35.57

***

在Cobalt昨晚的分享中,Teddy聽到幾個很有幫助的做法:

  • 以縮短交期(lead time)為做事原則:Cobalt他們採用許多Scrum實務做法與看板方法(Kanban Method)的精神,因為產品包含硬體設計,所以很難用iteration-based的開發方式在iteration開始的時候計畫這個iteration要完成的功能。因此他們採用看板方法的作法,針對專案的每一個工作項目,首先排列優先順序,在施工的時候運用各種方式儘量縮短每一個工作的lead time。因為觀念轉換,傳統上在硬體部門、韌體部門、軟體部門之間丟來丟去沒人管的工作,就由傳統工作流下游的軟體團隊一肩扛起,往上游追朔找與其他部門的人一起合作完成工作。
  • 說對方聽得懂的語言:Cobalt在演講中舉了一個例子,他們有一個案子因為硬體的限制需要把網路速度控制在100M,但原本的硬體設計並不支援。如果軟體團隊跑去跟硬體設計師說:「請把硬體改成網路速度控制在100M」那麼硬體的人會不知道你在說什麼,無從改起。但如果你跟他說:「把某個接線跳到另一個接線」那麼硬體的人就知道該如何做,也會很樂意幫忙。
  • 說明「為什麼」並請求協助:軟體團隊若只是一味地「指使」其他團隊的人改這個、做那個,對方可能會覺的「我為什麼要聽你的?」如果可以先跟對方說明遇到什麼問題,所以要做一些調整或改變,則比較容易得到對方的配合
  • PM很弱不一定是壞事:不管軟體或硬體專案,許多團隊都遇到「PM(專案經理)」有點弱(擺爛?!)的冏境,團隊成員除了碎念以外,還能怎麼辦?Cobalt提到其實團隊成員大可直接去面對客戶,既然PM不管事那就自己管,到頭來反而順利完成專案(自組織團隊的概念)
  • 把繁瑣的固定知識記錄在Wiki上:軟硬體整合的專案有很多關於設定的細節,如果設定錯誤便會造成系統無法運作。這些知識一定要在解決問題的當下趕緊記錄下來,以減少「重複學習」的浪費(精實開發的作法)。

***

Cobalt在整場演講中並沒有對於Scrum或看板方法作任何說明,而是用四個專案作為例子,告訴我們如何落實敏捷與精實開發精神。許多敏捷開發的初學者經常會糾結於「XXX算不算Scrum?」而忘了原本採用敏捷開發的原意—如何在競爭的環境中保持成功。Cobalt的演講以解決問題為出發點,選用任何可以幫助他們縮短lead time並保持持續改善精神的方法,是一場非常棒的分享。

***

友藏內心獨白:從人鬼殊途到通靈少女。

2017年4月27日 星期四

原力的黑暗面

April 27 05:45~06:48

腳踏實地

▲只擷取酸哥數百篇貼文的其中一篇這樣算是「合理使用」吧XD

 

可能是因為朋友按讚的關係前幾天在Facebook上看到外號「酸哥」的Ken Hsu的一篇貼文:「腳踏實地做事不難,難的是得忍著看見不老實的人賺的比你多。」對照到這兩天鬧得沸沸揚揚的谷阿莫「二次創作」事件,以及各種網路上流傳的詐神傳說,腦袋中突然上演了一篇篇「星際大戰」系列電影中安納金黑武士)與尤達大師還有白卜庭議長(西斯大帝)的對話。

絕地武士與西斯都是原力(force)使用者,不同點在於前者使用原力光明面,後者使用原力黑暗面。在「星際大戰三部曲:西斯大帝的復仇」中,白卜庭為了吸收安納金當自己的徒弟,於是唬爛安納金,表示黑暗原力具有起死回生的能力,他可以教安納金拯救他的「未公開老婆」佩咪,也就是前那卜星女王,免於難產死亡的命運。

安納金曾問尤達大師絕地武士這一派是否也有起死回生的「技能」,但尤達大師告訴他,生死有命,這就是原力的自然現象,請安心服用。尤達大師與其他絕地武士大師也曾多次說過,身為絕地武士,要抗拒黑暗力量的誘惑。反之,西斯大帝則是不斷利用憤怒、恨、忌妒等原力的黑暗面來獲取力量。

尤達大師曾經表示,原力的黑暗面並沒有比較強大,但也承認利用原力的黑暗面可以「速成」,但必須付出代價。

***

絕地武士終其一生都在學習著如何「腳踏實地」,多麼簡單也多麼困難的一件事。以前年輕的時候看星際大戰覺得很奇怪,怎麼「當個好人」有那麼困難嗎?都已經具備成為絕地武士的資質了,怎麼還無法對抗黑暗力量的誘惑 ?出了社會之後才慢慢發現,要抗拒黑暗力量還真的不容易。

你是否能抗拒:

一批便宜的牛肉

輕鬆賺大錢的投資方法

讓任何人都可以飛天找到好工作的訓練課程

把別人的創作收集起來當作自己的作品快速出版

用盜版手法獲取暴利

自我感覺良好的話術

***

古人有云:「不恥下問」,但「不恥」和「無恥」兩者之間還是有區隔的。一個人獲取知識、金錢或名聲的方法如果立基於無恥,只能恭喜他成為現代黑武士候選人。

***

友藏內心獨白:也不是人人都有資格成為黑武士。

2017年4月21日 星期五

例外處理壞味道:將例外當作控制流程

April 21 01:33~14:12

擷取

 

在〈例外處理壞味道(上)〉與〈例外處理壞味道(下)〉Teddy介紹了以下幾種例外處理壞味道(exception handling bad smells):

  • Return Code(回傳碼)
  • Ignored Checked Exception(忽略受檢例外)
  • Ignored Exception(忽略例外)
  • Unprotected Main Program(未被保護的主程式)
  • Dummy Handler(虛設的處理者)
  • Nested Try Statement(巢狀Try敘述)
  • Spare Handler(備胎)
  • Careless Cleanup(粗心的資源釋放)

昨天在北科上課review學生的作業,看到另一個很常見的例外處理壞味道:例外當作控制流程(using exceptions as control flow)

***

▼下圖是學生所寫的程式碼示意圖,getCompanyName函數首先判斷參數obj是否包含錯誤,如果是則丟出一個Exception並將其內容設為「找不到資料」。在第39行的catch clause中捕捉例外,然後傳回例外物件的getMessage字串。

屏幕截图 2017-04-21 01.48.25

 

問題一

有經驗的鄉民一眼就可以看出來上面這段程式出了什麼問題,首先在第29行丟出例外然後在第41行捕捉例外這種寫法就是典型的將例外作為控制流程,和寫go to是類似的效果。

▼程式可以改成當判斷obj物件包含錯誤的時候,直接傳回 “找不到資料”這個字串就可以了。

屏幕截图 2017-04-21 01.50.45

 

問題二

原本的程式寫法直接捕捉exception物件,這個物件在Java例外物件的階層中僅次於Throwable,捕捉Throwable或Exception這種寫法叫做blanket catch(請參考〈Java的try、catch、finally(1):Java SE 7之前〉)。在原本的程式碼中27~39行的try clause除了29行以外其他地方也可能會丟出例外,所以就算原本的程式碼不介意使用例外作為控制流程,41~43行的例外處理程式(exception handler)也可能因為其他程式發生例外而被觸發。也就是說,當呼叫getCompanyName函數的人收到"找不到資料"這個字串的時候,在原本的寫法當中有可能因為兩個原因所造成:

  • 真的找不到資料。
  • 因為發生例外被誤判為找不到資料。

很顯然地原本的程式邏輯是不正確的。

***

在絕大部分的情況下,例外應該單純用在程式異常狀況,而非因為丟出例外可以具有流程控制的特性而將例外使用在流程控制上。對於例外處理設計有興趣的鄉民們可以參考泰迪軟體的「例外處理設計與重構實作班」課程,或是Teddy所寫的《笑談軟體工程:例外處理設計的逆襲》 。

image

***

友藏內心獨白:程式不是看起來可以動就沒事了。

2017年4月10日 星期一

BDD(23)從規格、程式和測試思考BDD要解決什麼問題

March 31 12:30~13:24

屏幕截图 2017-03-31 12.38.07

 

前情提要

▲在〈三個圓圈(3):規格、程式和測試〉文章中Teddy介紹了上面這張圖的意義,並在文末留下一個問題:

有沒有什麼方法可以讓區域1變得越大越好?指派專人撰寫詳盡的規格書有幫助嗎?Design by Contract有幫助嗎?組cross-functional team有幫助嗎?BDD/TDD有幫助嗎?這些都是值得思考的問題。

今天從這張圖來思考BDD如何協助團隊把區域1變大。

***

瀑布式流程

在談論BDD之前先看看傳統瀑布式(Waterfall)開發方法,如下圖所示,在瀑布式流程中一開始是撰寫需求文件,也就是定義規格。雖然在定義規格的同時也應該一併把驗證方式準備好,但實務上很少有團隊可以做到,能把規格書在期限內生出來就已經很偷笑了(第一個圈圈)。

屏幕截图 2017-03-31 13.10.17

 

有了規格書之後,當然要請客戶畫押,發誓不再修改規格。之後再依據這份規格開始寫程式(第二個圈圈)。雖著時間演進程式越寫越多,但此時不知為何規格也跟著改變與膨脹(第三個圈圈)。好不容易等程式寫得差不多了,雖然沒有涵蓋全部的規格,但截止時間快到了,只好硬著頭皮先丟給QA部門測試(第四個圈圈),並且利用測試時間再繼續偷偷開發未完成的功能(第五~六個圈圈)。

以上所說都還算是負責任的情況,有時候趕著上市連最後的測試時間都沒有,直接丟給客戶請客戶幫忙測。在這種情況下,規格、程式和測試三者重疊的區域要大到哪裡去說真的不太容易。

***

測試後行的敏捷開發

敏捷開發團隊不須把所有規格都定義好之後才可以開工,以Scrum為例子product backlog有足夠接下來1~2 sprints的user story就可以了(第一個圈不需要很大)。下圖中的黑色圈表示規格,紅色圈表示程式,綠色圈表示測試。對於沒有導入BDD/TDD的敏捷開發團隊,開發順序先寫production code再寫test code,所以先有紅色圈再有綠色圈。基本上程式的範圍由user story的驗收條件所規範,而測試案例也可以參考這個驗收條件來撰寫。加上user story的粒度相較於傳統規格書的一個功能要小很多,因此比較容易讓規格、程式、測試三者重疊。

屏幕截图 2017-03-31 12.54.04

 

但是,有不少敏捷團隊雖然有事後「補寫」測試案例,但也常常因為sprint時間的限制只把程式寫完而來不及讓綠色圈與紅色圈重疊(測試不完整)。長期累積下來規格、程式、測試三者重疊的區域就大幅減低。

***

測試先行的敏捷開發

測試先行的作法利用測試案例來劃定規格的範圍,接著再撰寫程式。只要程式通過測試案例,既代表滿足規格所需。這樣的順序「理論上」可以大大地增加規格、程式、測試重疊的範圍。這裡有一個很重要的前提,使用測試案例所規範的需求要具備代表性,也就是《Specification By Example》書中所說的「關鍵範例(key example)」,否則一開始測試和規格重疊的部分就很小的話,後續依據測試所寫出來的程式也不可能涵蓋原本的規格。

屏幕截图 2017-03-31 13.03.32

***

結論

許多軟體開發方法都嘗試著增加規格、程式、與測試的重疊範圍。BDD透過兩個關鍵的做法來達到這個目的:

  • 透過協作來探索規格的範例。
  • 透過測試案例作為規格的代表,自動驗證規格與程式是否一致。

***

友藏內心獨白:BDD從流程上避免三者發散。

2017年4月6日 星期四

BDD(22)狀態與行為測試

March 30 18:15~19:23

屏幕截图 2017-03-30 18.25.00

 

測試術語

採用BDD開發軟體,首先你先寫一個失敗的驗收測試規範系統的行為與範圍,接著開發production code讓驗收測試通過。在寫production code的時候如果驗收測試無法清楚表達實作程式的行為,則可以進一步撰寫一個失敗的單元測試,然後再用最簡單、最直接、最無腦的方式來撰寫production code。等待單元測試通過之後,再拿出Refactoring(重構)這一把「小刀」,將剛剛快速撰寫的production code修剪一番,朝向clean code目標邁進;後者就是傳統上大家所理解的TDD。

無論是先寫一個失敗的驗收測試,或是失敗的單元測試,這個「待測物」(System Under Test;SUT)通常需要借助其他物件的幫忙來達成任務,例如資料存取物件(OAD)相依於資料庫,網路應用程式需要Socket物件來建立網路連線。這些相依物件稱為Depended-on component(DOC)Collaborator

一個SUT的所有DOC集合稱為這個SUT的Context。為了提高SUT的重複使用性與可測性,在設計上希望SUT不要自己管理Context,而是由外部將它所需要的Context傳入,這也就是Dependency Injection(DI)的作法。

以上名詞解釋完畢,可以回到BDD身上。開發人員撰寫這個「失敗的測試案例」,可以從兩個角度切入,分別是驗證狀態驗證行為

  • State-based testing:測試程式提供SUT所需的Context,然後呼叫SUT,最後驗證SUT的狀態是否正確。例如,傳入5給判斷質數的函數,傳回結果為true,如果傳入8則結果應為false。又例如push一筆資料到一個stack物件,則stack的容量會加一。以上做法都是藉由驗證SUT的狀態來判斷SUT的實作是否正確,有種黑箱測試的味道。
  • Behavior-based testing:測試程式根本不管SUT的執行結果與狀態是否正確,只關心SUT與DOC的互動是否有如預期。聽起來有點玄,但在某些時候卻必須做這種方式的驗證。例如在Observer設計模式中,當subject狀態改變會自動呼叫observer的update函數。如果想驗證的重點是Observer設計模式是否實作正確,則測試者根本不管也不關心subject的business logic到底是在做什麼東東,只要確定當它狀態改變的時候真的會呼叫一次observer的update函數就可以了。這種測試白箱的味道很重,因為測試者必須知道SUT實作的邏輯才有可能知道要如何驗證SUT如何與DOC互動。

***

測試替身

講了這麼多還是沒提到和BDD有什麼關係。當開發人員要讓失敗的測試案例通過的時候,這時候SUT與DOC很可能都還沒產生(因為production code還沒寫啊),如果一口氣要把SUT與DOC全部寫好讓測試通過,可能需要花很長的時間。因此為了讓SUT可以在比較短的時間通過測試,開發人員可以採用Test Double(測試替身)的技巧「欺騙騙」SUT,先專注於SUT的開發而暫緩DOC的實質內容,又可以讓測試案例通過。

因為測試方式有狀態測試與行為測試這兩種,所以測試替身也可以分成這兩大類。Dummy、Stub、Fake屬於狀態測試,而Spy和Mock則屬於行為測試。

Teddy習慣用Dummy、Stub或Fake來做狀態測試,較少用Spy或Mock,總覺得Mock Object Library,例如mockito這種工具用「設定期望值」的方式來做行為測試,程式碼不是那麼容易閱讀,過一陣子沒看還要想一下才知道在驗證什麼。另一方面因為mock object library具有「純屬虛構」的能力,有可能真正的production code行為已經改變但使用mock object library所撰寫的測試案例還是通過,這也是有點傷腦筋的地方。

▼用mockito測試Command pattern

屏幕截图 2017-03-31 10.22.05

 

但是mock object library也有它的好處,尤其在做BDD/TDD的時候它可以讓你比較快速的採用piece by piece的方式完成SUT而不用先把DOC用「老師傅手工打造」的方式手刻一個假的版本出來。對於行為有一定穩定度的程式,例如最常見的就是Observer設計模式,用mock object library會比手刻DOC簡單很多。

***

無論是使用哪種測試替身,程式碼終究還是寫給人看的。工具本身並無對錯,在合適的時機下使用合適的工具需要由人來判斷,很多時候如何判斷時機才是最難的點。

***

友藏內心獨白:Mock到最後連開發人員都被騙了。

 

延伸閱讀

2017年4月4日 星期二

【敏捷開發懶人包:物件導向技能】五月份平日班

March 31 09:00~09:35

擷取

 

敏捷開發懶人包:物件導向技能」已經開了三梯次,課程設定目標是希望鄉民們在找工作面試的時候,如果面試官問到物件導向技術方面的問題,能夠具備輕鬆回答的能力。上課方式第一次規劃以講解為主,但沒想到幾次下來增加了越來越多的活動、討論、與練習,排定的四小時上課時間不夠用。這次把課程時間調整成一日班,可以安排更完整的練習與討論活動。

課程內容也依據學員的回饋每次都稍加調整,對於下列人士特別有效:

  • 寫了多年的C程式,突然被叫去學Java、C#或是開發App,不知道如何著手用物件導向觀念作設計。
  • 寫了多年物件導向程式,但不確定自己是否用正確的方法使用它。
  • 想知道有沒有比較好的方式可以設計物件介面與分配責任。
  • 軟體設計如何有彈性地應付改變?
  • 物件導向分析與設計到底在講什麼東東?
  • 我沒有時間與耐心慢慢學會以上這幾個問題。

 

▼課程照片

屏幕截图 2017-03-31 09.54.10

 

Teddy挑選以下幾個最常使用的重要主題加以介紹,快速幫學員打底,補充身體所缺乏的「物件導向養分」:

  • 物件導向基礎觀念
    • 封裝、多型繼承
    • 耦合、內聚
    • 介面、委託、聚合
    • 物件導向與程序導向之優缺點比較
  • 依合約設計(Design By Contract)
    • 為什麼防衛式程式設計不好?
    • 前置條件、後置條件、類別不變量
    • 違反合約:例外處理機制
    • 合約與繼承
    • 依合約設計(DBC)與測試驅動開發(TDD)比較
  • 物件導向設計原則這樣聽就懂了
    • S.O.L.I.D.五大原則
  • 物件導向分析與設計
    • 問題敘述
    • 環境圖
    • 分析模型
    • 設計模型
  • 實例討論

上課日5月16日(週二) 09:30-14:30,共六小時。

image

***

友藏內心獨白:可快補充不足的物件導向能量。

2017年4月3日 星期一

說故事的技巧:Yes, And

March 31 08:23~08:54

屏幕截图 2017-03-31 08.51.48

▲畫面節錄自Google搜尋結果

 

前幾天和Erica聊天,他說在一門即興表演的課程中學到一種講故事的技巧:YesAnd

Yes就是把別人說過的話用不同的方式再講一次,例如:「小紅帽被大野狼吃掉了;大野狼吃了小紅帽」,而And則是在原本的情節中加入新的內容,例如:「小紅帽被大野狼吃掉了,大野狼穿了小紅帽的衣服,假裝成小紅帽打算連老奶奶一起吃掉。

後來聊到在臉書上許多朋友分享的資訊,也可以分成Yes、And這兩種。Yes派的擅長不斷地轉述別人講過的話、轉貼網路上的文章,以分享之名行刷存在感之實,如果能意外造成「自己也好棒棒」的形象那就更好了。And派的也會轉述與轉貼,在刷存在感的同時還會上加幾句自己的看法,算是盡到一點點「資訊加工」的責任。

***

Teddy覺得Yes,And這種看法很有趣,也可以應用於學習之上。有些人在上完課之後會不斷重複上課中所聽到的「洗腦口號 名言佳句」,但腦袋中的知識只是上課教材的子集合而已,並沒有舉一反三的能力也無後續的自學行為,很顯然是採用Yes的學習方法。也有人上完課之後引發後續的一連串學習行為,所學範圍已大大超出原本上課的內容,這是And的表現。

不少人為了證照、口號、安全感而學習,Yes + Yes + Yes …,不管多少個Yes,如果沒有後續的And,就好像鸚鵡一樣,只是學人講話的音調,就算再多學幾句話,鸚鵡還是鸚鵡,不可能變成人。

你會想跟鸚鵡說話嗎?一開始覺得有趣,看透了之後就乏味了。

***

友藏內心獨白:要平衡Yes與And。

2017年3月31日 星期五

5月【例外處理設計與重構】平日班

March 31 07:40~08:16

螢幕快照 2013-09-13 下午9.07.53

▲看到這樣的網路銀行畫面用起來心裡會不會毛毛地?

 

有一句閩南語俗話是這樣說的:「生吃都不夠,哪還有多的可以曬乾?」這句話很確切的點出例外處理的處境—「開發正常功能的時間都不夠,哪還有多餘的時間去處理例外狀況?

沒有多餘的食物拿來曬乾不打緊,但軟體系統沒有好好地處理例外狀況卻是很嚴重的問題。不穩定的系統輕則無法提供正常服務給使用者,重則造成使用者時間、金錢甚至是生命安全的危害。強調使用者體驗的今日,系統穩定度不良的問題,絕對不是請使用者重開機或是不斷地重新載入(reload)網頁就可以輕鬆帶過

螢幕快照 2014-01-02 下午11.48.05

▲Facebook錯誤畫面,大拇指受傷比讚就不好看了啊XD

***

身為專業軟體開發人員的各位鄉民,從小到大一定學過各式各樣的軟體設計技術與方法。從最基礎的程式語言、資料結構與演算法,到物件導向分析與設計、設計模式、軟體架構,以及各種敏捷開發實務做法,包含自動化測試、測試驅動開發、行為驅動開發、持續整合、敏捷設計原則等。以上,所有的大師費盡一生心力,都在告訴各位一件事:「如何設計軟體的光明面,也就是『正常行為』(normal behavior)」。而Teddy要告訴鄉民們,如何對付軟體的黑暗面,也就是『異常行為』(abnormal behavior)。唯有正常與異常的行為「陰陽調和」,軟體才可以提供正常且穩定的服務給客戶。

***

例外處理設計與重構實作班】專治例外處理疑難雜症,適合以下人士:

  • 經常因為系統當機,而被主管、老闆與客戶痛罵者…Orz
  • 對設計高強健度軟體系統有興趣者。
  • 想深入並徹底了解例外處理設計者。
  • 因為例外處理不良導致系統一直當機者。
  • 想知道如何在敏捷開發中,以逐步成長的方式來增進系統強健度者
  • 想開發出穩定的軟體,借此賺大錢者。

***

課程介紹與報名網址在此【看板方法與精實開發實作班】,上課日期2017年5月2、3日(二、三)。

image

***

友藏內心獨白:想成為絕地武士須先克服黑暗力量。

2017年3月29日 星期三

BDD(21)從測試金字塔看BDD的自動化驗收測試

March 28 23:40~24:00; March 29 00:00~00:58

屏幕截图 2017-03-29 00.57.19

▲畫面節錄自Google搜尋結果

 

前輩的測試金字塔

在〈BDD(18)這是一個End-To-End的Scenario嗎?〉、〈BDD(19)幫開發票功能加上使用者介面的三種方法〉和〈BDD(20)使用者介面細節放哪裡〉Teddy花了三集討論了使用者介面和BDD的關係,故事還沒結束,今天從「測試金字塔」(Test Pyramid)的角度來思考這個問題。測試金字塔的概念由Mike Cohn描述在《Succeeding with Agile》書中,多年來已經有各方人馬提供各自版本的測試金字塔。

▼Mike Cohn原始版本。

屏幕截图 2017-03-28 23.52.27

 

▼下圖節錄自Martin Fowler的版本,左邊用烏龜和兔子用來代表不同類型測試執行速度快慢,右邊用錢來代表對使用者的價值,UI測試的價值最高,單元測試的價值最低(因為使用這看不到)。

屏幕截图 2017-03-28 23.54.50

 

▼下圖取自agilefaqs網站的〈Inverting the Testing Pyramid〉文章,左手邊為傳統專案中的測試金字塔,大部分為人工手動測試,其次為自動化GUI測試,再來則是整合測試,單元測試所佔比例最少。但這是不健康的現象,因為占比最多的人工測試與自動化GUI測試的執行很耗時,且維護成本高,找到問題之後debug的時間也很長。執行速度最快,且最容易避免系統缺陷的單元測試反而最少,所以應該把左手邊的測試金字塔反轉過來,變成右手邊這樣。

image08

 

上圖的測試種類分得十分詳細,而且還包含每種測試所佔的比例。基本上從Biz Logic Acceptance Tests到End to End Flow Tests之間的測試都可以視為傳統軟體測試所說的整合測試(Integration Tests),或對應到Mike Cohn版本的Service測試。

***

Teddy的測試金字塔

▼綜合上述說明,加上網路上找到的資料以及這一陣子讀的書,Teddy把測試金字塔畫成下圖。
屏幕截图 2017-03-29 00.27.55

 

首先看到中間的金字塔本體,一樣是三大層,Teddy把中間層叫做驗收測試(Acceptance Test)原本Teddy是採用傳統軟體測試中整合測試這個名稱,但後來想一想,從「目標導向」的角度思考,這中間層的整合測試,其目的應該是要「驗收」一群軟體物件或元件之間的協作是否如預期,所以改成驗收測試覺得目標比較明確。

圖的右方把驗收測試展開之後,是沿用〈Inverting the Testing Pyramid〉的分類,驗收測試細分之後包含商業邏輯驗收測試、傳統的整合測試、工作流程的驗收測試、以及在GUI下一層的End-To-End流程驗收測試。用這種方法分類,和BDD的流程與工具就可以配合得很好。為什麼,請看以下說明。

圖的左邊是從工具觀點來看金字塔的三層,最底層是單元測試,可以用xUnit系列工具或Spock與RSpec。往上一層驗收測試層,這一層的最頂層「End-To-End流程驗收測試」,可以用BDD工具像是Cucumber或Fitness來開發,其他下層的測試則可以沿用單元測試工具。 這樣的對應關係恰好是Teddy在〈BDD(18)這是一個End-To-End的Scenario嗎?〉文章中所討論內容,一個位於GUI下一層的End-To-End流程測試,這是一種驗收測試,用來驗收Scenario(或 User Story)的測試。

至於最頂層的GUI測試,通常是從使用者的角度所執行的測試。因為自動化GUI測試建置、維護與執行的成本高,為了減少這類測試案例的數量,在設計上應該考量使用者最關注的系統重要功能開始撰寫。自動化的工具如果是網頁則可以採用Selenium,桌面程式與手機APP也有相對應的GUI自動化測試工具。

在這裡要提醒一點,上圖中的驗收測試(Acceptance Test)與使用者驗收測試(User Acceptance Test;UAT)不同,UAT需透過GUI來執行,而這裡的驗收測試則是採用「目標導向」的觀點對於傳統整合測試的另一種稱呼。

***

結論

如果採用Teddy所介紹的測試三角形觀點,則BDD的驗收測試就可以「名正言順」的和GUI脫鉤,而在需要掛鉤的時候參考〈BDD(19)幫開發票功能加上使用者介面的三種方法〉文章中介紹的方法。在此Teddy要強調這只是Teddy自己的觀點,並不是說BDD一定採取這種做法。實際上在《Growing Object-Oriented Software, Guided by Tests》(GOOS)書中就主張驗收測試一定要跨越應用程式的每一層,也就是需要從GUI開始進入系統,如此方可達到兩種不同的End-To-End效果:

  • User Story
  • Process

但Teddy認為就算是採用本文建議的作法,也還是可以吸納GOOS書中的好建議,讓BDD的Scenario串起End-To-End Process,只不過Scenario的入口點採用「可插入」(Pluggable)的方式,不一定是哪一種特定的UI,可以是Web UI、Console UI、手機UI。因此,稍微延緩一下定義UI的時間點對於End-To-End Process的建立所造成的負面影響應該可以想辦法降到最低。

***

友藏內心獨白:感覺快要可以寫一篇論文了…Orz。

2017年3月28日 星期二

Fail Fast不是這樣用的吧?!

March 28 09:12~10:53

屏幕截图 2017-03-28 10.34.39

▲畫面節錄自Google搜尋結果

 

認識Teddy的人都知道Teddy是一個講話非常不中聽的人,也因此在有意、無意中經常得罪人。記得有一年Teddy去拜訪一位朋友,朋友說他們正在跟某公司合作,該公司已經跑Scrum三年多了,成效斐然。聽到台灣有這麼棒的團隊,Teddy很好奇的問:「請問他們的自動化測試和持續整合做到怎樣的程度?」聽到這個問題朋友突然顧左右而言他,快速轉到其他話題上。

文化上的改變先不談,一個跑了三年多的Scrum團隊自動化測試和持續整合都做不好,你說這個團隊好棒棒實在很沒說服力。

***

有位鄉民和Teddy聊BDD(Behavior Driven Development,行為驅動開發),他說他們導入BDD已經一年多了,Teddy非常有興趣,想多了解對方這一年多來實踐BDD的經驗。但聊來聊去都聊不出個所以然,問他如何在BDD中落實DDD(Domain Driven Design)他說從來沒聽過DDD,再問他開發團隊如何和PO或stakeholder協作討論規格與範例,他說他們的規格是「別人」給的。講到最後才發現原來這個朋友口中的BDD是「功能做好之後用Selenium補寫(錄製?)自動化驗收測試」。

這是九二共識的軟體版嗎?

一個BDD各自表述。

***

某位鄉民和Teddy聊到User Story Mapping(使用者故事對照,USM),對方說他參加公司內部的讀書會,把書讀過一遍之後的感想就是使用者故事對照只適合用來管理循序(有單一時間操作順序)的功能,對於多重路徑(有選擇條件)或時間順序不一定的功能無法用使用者故事對照來表示。Teddy第一次讀這本書的時候也是有同樣的疑惑,把使用者的歷程依據時間軸展開,這不是把真實世界中,系統平行、重複或多重選擇路徑硬簡化成單一時序的使用情境嗎?這種方法有用嗎?要表達時間順序不是用UML裡面的sequence diagram (循序圖)就好了,何必再學另一種工具呢?

經過更仔細的閱讀之後,才發現自己一開始只看到使用者故事對照的形,根本沒看懂它的精髓。時間順序只是一種讓你講故事的方法,因為從時間順序來思考最直覺也簡單。有了故事之後,引發團隊討論,驗證大家腦袋中的想法,最後獲得共識,這才是背後的目的。試想,一個產品或服務,你說它時間順序不明顯,無法說故事,那你產品做好之後要怎麼賣?最後還不是要用說故事的方式賣給客戶,總不能把所有規格一條、一條列出來就要客戶買單吧:

4個USB Type C、15” 2K螢幕、觸感不佳的二代鍵盤、超大觸控板、無三小路用Touch Bar、16GB RAM、512GB SSD

如果只看規格,誰想買「貴森森」的MacBook Pro(MBP),類似規格價格便宜的產品選擇很多。相信很多人是因為被產品背後的「故事」—以及故事所帶來的用戶體驗,不管是真實體驗還是自行腦補後的想像體驗—給吸引。功能不是不重要,相反地功能很重要,但必須能夠串起來幫助使用者達成任務(解決問題)才可以傳遞價值。

如果無法說故事,會不會是因為還沒把產品的價值想清楚,還停留在比規格、比功能數量的思維上面呢?

***

敏捷、敏捷,大家都想要求快,就算這個快是很膚淺的快也無所謂,反正先丟出去再說,先說先贏。敏捷不是說fail fast嗎?人是很奇妙的生物,大家經常抱怨政府推出的政策都在炒短線,口號喊著漫天價響,很少做長遠規劃。但輪到自己做事的時候才發現,原來做長遠規劃這麼辛苦,而且又不能時時刷存在感,這樣子怎麼提高民調數字哩?算了,還是也來學政府開放「現股當沖」,先把交易額炒高再說。

學習原本就沒有說一定要「全學會」才可以,學一點、用一點是很正常的現象。怕就怕「學一點」卻以為全部學會,「守、破、離」三個階段都還沒開始「守」就已經不知道「離」到哪裡去了。學習的「量」(廣度)和「質」(深度)之間應該取得平衡,才不至於淪為口號收集器。

俗話說:「滾石不生苔,轉業不聚財。」學習還沒到守的階段就已經換題目,大概離詐神不遠矣。

***

友藏內心獨白:詐騙手法也是要推陳出新。

2017年3月24日 星期五

BDD(20)使用者介面細節放哪裡

March 24 08:20~10:32

屏幕截图 2017-03-24 10.24.05

 

昨晚C. C. Agile活動Teddy分享「SBE、BDD、ATDD、TDD、DDD大亂鬥」,Teddy提到Scenario應該避免描述太多使用者介面的細節,會後有好幾位朋友都問到BDD和使用者介面描述的問題。今天先把時間倒轉,回憶N年前Teddy還在用Use Case描述需求的時候,遇到關於使用者介面的問題。

 

怎樣算使用者介面細節?

首先看一個ATM提款的例子:

Use Case: 提款

  1. 系統顯示歡迎畫面
  2. 使用者放入提款卡
  3. 系統驗證提款卡
  4. 系統顯示輸入密碼畫面
  5. 使用者輸入密碼
  6. 系統驗證密碼
  7. 系統顯示交易選單
  8. 使用者選擇提款
  9. 系統顯示提款金額畫面
  10. 使用者輸入提款金額
  11. 系統驗證使用者存款餘額,確認使用者存款大於提款金額
  12. 系統詢問提款後是否繼續交易
  13. 使用者選擇否
  14. 系統退出提款卡
  15. 使用者拿取提款卡
  16. 系統扣除使用者帳戶內的提款金額
  17. 系統吐出鈔票
  18. 使用者拿取鈔票

Use Case描述系統與使用者的互動關係,上面這個Use Case有18個步驟,請問它有包含使用者介面細節的描述嗎?

提款Use Case的確描述了使用者介面,例如「歡迎畫面」、「輸入密碼畫面」、「交易選單」、「提款金額畫面」,這些使用者介面有些扮演「操作流程串接」的角色,有些則是負責接收使用者提供的資料當作系統的輸入,但Use Case中並沒有提到特定的使用者介面元件,例如按鈕、文字框、顏色、元件位置、元件的ID等資料,初步看起來並沒有描述「使用者介面細節」。

但是,有些人卻認為光是「使用者放入提款卡」這個敘述就是一種使用者介面細節。What The Fxxx…李組長眉頭一皺,為什麼放入提款卡算是介面細節哩?

因為這個描述背後的目的其實是「使用者出示可代表其身分的辨識物」,這個物品可以是提款卡、指紋、眼睛虹膜、臉部辨識、聲紋辨識、QR Code、甚至是一串代碼,而提款卡只是其中一種選項,所以算是實作細節。當然也有人認為這樣子太吹毛求疵了,我家的提款機打死就只支援提款卡,其他的方法一概都不支援。Use Case裡面直接寫出示提款卡不是清楚明白多了,搞什麼抽象化描述哩。

***

需求 VS 設計

雖然提款這個Use Case清楚交代使用者與系統的互動流程,但並沒有包含詳細的畫面。不是都說用戶體驗很重要嗎,如果不提供UI畫面讓Product Owner或stakeholder確認,到時候系統出來才來打槍那不是浪費大家的時間。N年前Teddy的作法是寫好Use Case(需求)之後用VB拉出假畫面(設計),跟客戶討論需求的時候一邊讀Use Case內容一邊對照著假畫面,這樣子客戶比較有「即視感」。Teddy第一次用這種方式做案子的客戶是「洗衣業」,客戶以前從來沒有遇過這種討論需求的方式,但他們卻非常接受這種方式,透過Use Case與假畫面來驗證他們內心對於產品的期望。

使用者介面是一種設計,依據「規格」或「需求」所產生的設計。規格來自於目標,目標定義專案範圍,必須先釐清目標、協作探索規格與範例,再依據規格產生介面設計。如果用相反的方式來產生需求,也就是透過使用者介面來「規範需求」,很可能導致疏於探索使用者需要系統的真正目的(沒有做到do the right thing),而且商業邏輯和介面邏輯混在一起,無助於建立豐富的領域模型(domain model)

需求與設計的界線經常並不是那麼黑白分明,回顧一下《Specification By Example》書中的這張圖,步驟1~4屬於需求探索的階段,步驟5~6屬於實作。雖然思考實作的時候很可能會回頭調整需求,這是一個迭代的過程,但大體來說還是必須從使用者的目的開始思考,由上往下展開。直接從使用者介面(而不是從使用者目的)思考,因為這已經是在討論一種設計方式,很容易卡在介面細節上,例如,icon美不美觀、字要大一點、小一點、畫面layout與配色怎麼安排,而忘了原本想達到的目的是什麼。最後就算是產品的品質很高,畫面精美,但因為需求搞錯方向,變成do the wrong thing right也是白搭。

屏幕截图 2017-03-22 09.48.24

***

啊不然介面細節要放哪裡?

下圖節錄自《BDD in Action》,軟體開發的規格依據需求與實作可分成:

  • 需求規格:在BDD中用Feature檔案與Scenario來表達,這也對應到specification by example的概念,可以使用Cucumber或SpecFlow這類的工具來表達。
  • 實作規格:用單元測試或RSpec、Spock來記錄。

屏幕截图 2017-03-24 09.54.45

 

但是以上都沒提到使用者介面細節。沒錯,Teddy認為BDD與OOAD對於規範與紀錄使用者介面細節的助益不大,它主要關注系統行為與實作(domain model)的規格,而非使用者介面。使用者介面怎麼設計,應該用它自己的規格或設計方式與文件,這種文件的目的並不是期望開發人員撰寫類似Cucumber的step definition將其自動化,而是提供給人機介面設計師實作參考。至於驗證使用者介面的目的,則應思考:

  • 系統中大部分的自動化測試案例應該是單元測試,約佔70%。
  • 自動化GUI測試應該是最少的,介於1%~5%之間。
  • GUI儘量不要包含複雜的邏輯,可以簡單到不太可能出錯就不需要太多自動化測試。
  • 當人工測試的投資報酬率大於自動化GUI測試的時候,採用人工測試即可。

***

友藏內心獨白:是行為驅動(behavior driven)不是介面驅動(GUI driven)。

2017年3月23日 星期四

[還少一本書] BDD in Action

March 23 05:52~07:05

屏幕截图 2017-03-15 15.35.30

 

昨天介紹完《Specification By Example》今天緊接著介紹《BDD in Action》,這兩本書都是Manning出版社所出版。從約20年前買了一本Manning出版的Java網路程式設計的書之後,Teddy一直都很喜歡這個出版社的書。如果要學一樣新技術,Manning所出版的書一定是Teddy優先考量的對象。昨天提到《Specification By Example》書中介紹7個流程模式,並沒有介紹工具也沒有程式碼。《BDD in Action》剛好跟它互補,講了很多工具與程式碼。對於學習BDD的人來說,這兩本書一起服用效果更佳。

***

看圖說故事

▼下圖節錄與修改自《BDD in Action》。

屏幕截图 2017-03-23 06.12.01

 

圖中將BDD開發流程分成6個步驟,和昨天介紹SBE的7個流程模式很接近:

  • Business goal:這一步對應到昨天SBE提到的第1個流程模式Deriving scope from goals
  • Features:這一步可視為SBE第2個流程模式Specifying collaboratively的產出物。
  • Examples:相當於SBE第3個流程模式Illustrating using examples
  • Executable specifications:相當SBE第5個流程模式Automating validating without changing specifications
  • Low-level specifications:從這個步驟開始則是銜接到傳統以單元測試為主的TDD範圍,這裡的low-level specifications就是TDD中的第一個步驟,先寫一個失敗的測試案例作為production code(application code)的規格。
  • Application code:就是TDD的第二個步驟,撰寫production code。如果完全對應TDD應該還有第7個步驟Refactoring(重構)才對,但上圖並沒有把Refactoring特別獨立成一個步驟,所以這個步驟可以看成寫production code加上Refactoring。

上圖步驟1~4可以視為傳統上BDD/ATDD的主打範圍,而5~6則是傳統TDD的守備範圍,而步驟4銜接到步驟5則是Teddy在〈BDD(12) 第二個開發票Scenario:從BDD到TDD〉與〈BDD(13)新劇情找到新Bug〉所介紹的轉換過程。

***

把圖展開

上圖並沒有包含SBE其他三個流程模式:Refining the specification、Validating frequently、Evolving a documentation system,下圖是書中上圖的原圖,可以看到步驟4~5展開後,包含了:

  • Living documentation:對應到SEB的Evolving a documentation system
  • Real-time progress reports:對應到SEB的Evolving a documentation system
  • Technical documentation:對應到SEB的Evolving a documentation system
  • Automatic validation:對應到SEB的Validating frequently
  • Working feature:對應到敏捷宣言的Running software或Scrum的Potentially shippable product increment。

屏幕截图 2017-03-23 06.38.22

 

雖然圖中還是沒有特別標示SBE的Refining the specification這個流程模式,但只要把步驟2和步驟3解讀成來回探索的過程,就等於對應到Refining the specification流程模式。

***

如何閱讀

Teddy是先讀了《Specification By Example》(2011年出版)之後才讀了《BDD in Action》(2014年出版)。第一次閱讀《Specification By Example》的時候因為書中完全沒有程式範例,光是看到書中對於這7個流程模式的文字說明覺得稍嫌抽象。後來讀了《BDD in Action》之後,整個感覺的豁然開朗了起來,兩本書互相對照,幾乎可以說《BDD in Action》就是《Specification By Example》這本書的具體範例啊。

對於沒有讀過這兩本書的鄉民,看完這兩篇介紹之後,Teddy建議直接讀《BDD in Action》再回頭讀《Specification By Example》這種閱讀順序。但是,讀《BDD in Action》也有一點小門檻,因為書中所介紹的工具與程式範例非常多,真的要全部搞懂需要很有耐心學習。

***

友藏內心獨白:讀書也需要實例化範例參考比較容易理解啊。

2017年3月22日 星期三

[還少一本書] Specification By Example

March 22 09:00~10:54

屏幕截图 2017-03-15 15.39.38

 

今年因為在北科兼任的「軟體生命週期管理」課程中教BDD,加上明天晚上在C. C. Agile要分享「SBE、BDD、ATDD、TDD、DDD大亂鬥」這個題目,從農曆年後又把《Specification By Example》(以下簡稱SBE)這本書拿出來讀了一次。第二次讀這本書比較有感覺,趁著記憶猶新的時候介紹這本書的內容。

 

從封底開始看

這本書的內容在英文版的封底已經簡短提示四個重點:

  • Common process patterns:本書包含7個「process patterns」(流程模式),書中從Part 2開始用了7章的篇幅來逐一介紹這7個模式。雖然作者用「模式」這個詞彙來介紹他所提出來的7個套用SBE的流程,但書中並沒有使用大家熟知的模式格式。作者提到用模式來記錄SBE的知識還需要一段時間,所以他先把手邊有的資料用比較隨興的方式介紹。希望假以時日這些知識可以被整理成更正式一點的模式,造福像Teddy這種模式愛好者。
  • How to avoid bad practices:既然書中提到7個流程模式,自然就會提到那些不好的做法會偏離這些模式,以及如何避免誤踩雷區。
  • Fitting SBE in our process:書中介紹的7個流程模式並沒有綁定任何特定工具,讀者融會貫通之後可以自行吸納到自己的開發流程之中。例如,在Scrum、XP或Kanban中套用SBE。
  • 50+ case studies:模式之所以被稱為模式,是因為模式針對重複出現的問題提出一個通過驗證的解決方案。本書是作者訪談超過50個案例並加以研究之後所整理出的7個流程模式,書中有大量的業界實踐SBE的佐證資料。書中Part 3特別用了6章來詳細介紹6個不同的案例,值得參考。

***

7個流程模式

本書的7個流程模式為:

  • (1)Deriving scope from goals:專案的範圍要如何界定?如果沒有目標,在專案進行的過程中一下子業務說加入A這個功能產品絕對超級賣,行銷說沒有B這個功能無法跟別人競爭,老闆說A.B…Z這幾個功能優先權都是1。照單全收的情況下最後導致功能膨脹,但預計上市的時程又不能延後。開發人員只好加班趕工,想辦法讓系統「看起來可以動」先過了這一關再說。專案團隊成員爆肝也就算了,更慘的是東西好不容易做出來才發現並不是客戶心中所想要的。沒有人要對這一片混亂負責,最後又怪開發人員做太慢、bug太多。

以上慘劇每天都在發生,這當然是大家想要避免的。所以專案的範圍必須從目標作為出發點,思考這個專案到底要給客戶和公司帶來什麼好處,採用「以終為始」的思考方式,對於達成專案目標沒有直接貢獻的功能應該加以排除,以免做白工。

  • (2)Specifying collaboratively:目標確定之後專案的規格要由誰來定?剛學Scrum的朋友可能會說:「需求是Product Owner負責的啊」需求是由PO排定優先順序這是沒錯,但並不是說所有需求都是PO一個人寫出來的。從敏捷開發的角度來看,需求是團隊一起討論出來的,這當然包含團隊與stakeholder的互動。SBE更加強調這一點,因此提出協作制定需求規格的建議。
  • (3)Illustrating using examples:規格不管是由一個人或是團隊討論而得出,不同的人對於相同規格總是有不同的解讀,這是因為語言與文字存在著模糊性。例如,雖然法律以及大法官對於警察臨檢有著明文規定與解釋令,但不同人對於「警察是否可要求穿拖鞋到小七買飲料的歐吉桑出示身分證」這件事卻很可能有著截然不同的見解。如果可以搭配案例(example)來輔助說明規格,如此不但可以減少對於規格的誤解,這些案例還可以做為日後相同事件發生時的檢驗標準(驗收測試)

屏幕截图 2017-03-22 10.25.40

 

  • (4)Refining the specification:理解與梳理規格是一個迭代的過程,隨著案例一個、一個出現,專案團隊與stakeholder對於規格越來越清楚,因此需要回頭整理原先的規格。
  • (5)Automating validating without changing specifications:等到規格與例子都整理得差不多了之後,就可以開始自動化。這個自動化的過程對應到Cucumber工具就是撰寫step definition,Teddy在BDD系列文章中已經舉過很多次例子。第5條流程模式的重點是:「自動化驗證而無須修改規格」,要做到這一點剛開始並不是很容易,實際做法可參考〈BDD(19)幫開發票功能加上使用者介面的三種方法〉。
  • (6)Validating frequently:既然已經把對於規格的驗收條件給自動化了,就必須要經常驗證這些條件,以確定系統進度與確保系統品質。
  • (7)Evolving a documentation system:最後,這些可自動執行與驗證的規格、例子與程式介面便成為系統的活文件(living documentation)。因為文件內容是由stakeholder與專案團隊共同討論,而且文件與程式碼隨時保持同步,因此是具備實際參考價值的活文件,而不像很多專案文件與程式已經不同步,變成沒有參考價值的死文件。

▼以上7個流程模式可以用下圖表示

屏幕截图 2017-03-22 09.50.59

***

讀中文版還是英文版?

經過Teddy這一番解釋,鄉民們先在腦袋裡面建立起這本書的概念圖,然後再去讀這本書應該比較容易看得懂。這本書有出正體中文版,Teddy也買了一本,內容翻譯的不錯。但是,Teddy對於正體中文版有一點覺得非常、非常的傻眼,那就是:「Specification By Example為什麼要翻譯成『Spec.實例化』?」把一個完整的名詞拆成兩半,前面用英文後面用中文讀起來真的不太習慣,讀正體中文版的時候每看到一次「Spec.實例化」就好像撞到一次牆一樣,思緒就被中斷一次。為什麼不用「實例化規格」、「規格實例化」或是直接用SBE都好。因為這個名詞貫穿整本書,用了「Spec.實例化」這個翻譯真的讓Teddy每看到一次心中就碎念一次啊。

***

友藏內心獨白:這是介紹SBE還是介紹Pattern啊。

2017年3月21日 星期二

【工商服務】看板方法:科技企業漸進變革成功之道(平日班)

March 21 07:50~08:13

屏幕截图 2017-03-21 07.59.54

 

你的專案遭遇到很多問題:一個團隊同時需要處理多個專案、時程延遲、團隊士氣低落、人員流動率高、加班情況嚴重、技術停滯不前、老闆或業務單位不斷地塞新需求。針對以上問題,Scrum敏捷開發法提供了不錯的解法,但是正所謂施政要「因地制宜」,治病要「對症下藥」,有時候Scrum這帖藥方可能不適合你的公司或團隊,因為:

  • 公司採用瀑布式(waterfall)開發流程,短時間不太可能改成Scrum這種敏捷方法。
  • 你是專門搶案子的資訊服務業者,你的團隊手上同時負責很多專案,而Scrum建議一個人最好同時間只處理一個專案,和你的現況衝突。
  • 你的團隊主要在開發新產品,但三不五時會有舊產品的維護需求跑出來,而且這些臨時性的需求都很急,必須要立即處理,因此打亂了Scrum的開發步驟。
  • 你的工作內容與「消防隊員」類似,專門處理突發事件,例如使用者回報的bug修正、客訴案件、公司IT維護與營運專案,不容易在固定的時間點(每個sprint開始的時候)朝開會議安排工作,而需要採用事件驅動的方式,即時的處理需求。
  • 你的團隊成員比較無法一下子接受過於激烈的組織與工作模式調整,依據Scrum的建議立即組成跨職能團隊(cross-functional team)。
  • 雖然可以從Scrum的工作看板(task board)得知每項工作狀態,但標準的工作看板只有「位施工」、「施工中」、「已完成」這三個狀態。你想要可視化更詳盡的工作流程,並從其中觀察出工作瓶頸以求改善之道。
  • 你是老闆、高階主管或專案經理,其實你不關心什麼敏捷不敏捷、精實不精實的,你只想要有一種比較好的方法來管理專案,方便你「切票(切割工作)」和「派票(分派工作)」,以及知道團隊的進度、工作效率和生產力。
  • 你已經採用Scrum,執行成效還不錯,但在開發流程與品質的持續改善方面遇到瓶頸。

 

如果你的專案具有以上任何一種「症狀」,都值得了解另外一種新的敏捷/精實開發方法:看板方法(Kanban Method)。看板以「可視化現有工作流程」為起點,先不要求團隊做出巨大的改變,以減少採用新方法的抗拒。接著,依據團隊的現有人力,設定每一個工作階段的同時施工項目上限,以協助團隊成員聚焦於「把工作完成」,而非不斷地製造「賣不出去的半成品」。 透過視覺化工具,看板方法可協助團隊找出工作瓶頸,並藉由五步驟聚焦法協助排除瓶頸,達到改善團隊工作效率,提升工作品質的目的。

看板可以應用在以下狀況:

  • 幫助新創公司要管理開發流程以便快速找到市場定位
  • 協助開發團隊有效管理手上同時進行的多個專案
  • 增進Scrum團隊的敏捷性與觀察問題的能力
  • 協助擴展大型敏捷開發團隊(例如Scaled Agile Framework, SAFe)
    • 管理IT維護與營運專案的事件驅動型工作
    • 以漸進且比較無痛的方式實施敏捷開發方法
    • 透過視覺化管理工作流程以便觀察與突破工作瓶頸

     

    螢幕截圖 2015-04-26 21.36.24

    ▲課程實況照片。

    ***

    報名網址在此:【看板方法與精實開發實作班】,上課日期2017年4月25、26日(二、三)。

    image

    ***

    友藏內心獨白:流程改善從此開始。

    2017年3月20日 星期一

    BDD(19)幫開發票功能加上使用者介面的三種方法

    March 20 08:01~10:08

    屏幕截图 2017-03-20 09.51.35

    ▲終於要幫開發票功能接上使用者介面了

     

    前言

    在〈BDD(18)這是一個End-To-End的Scenario嗎?〉提到scenario儘量不要描述太多使用者介面(UI)的細節,如果要透過UI做自動化驗收測試則可以把連結到UI的程式碼寫在step definition裡面。今天介紹在「開三聯式發票scenario」加上網頁介面的三種方法。

    ***

    直接修改Scenario

    ▼第一個最簡單的方式就是直接修改scenario,加上透過UI操作系統的描述。例如把原本的scenario從這樣:

    屏幕截图 2017-03-20 08.29.10

     

    ▼加上「Given I am on the invoice Web page」步驟,改成這樣:

    屏幕截图 2017-03-20 08.30.01

     

    ▼如此一來只要在「Given I am on the invoice Web page」的step definition中連結到操作invoice功能的網頁就可以透過UI讓這個scenario變成完整的end-to-end scenario。

    屏幕截图 2017-03-20 08.36.23

     

    ▼這種方法並沒有描述UI細節,只增加一個步驟描述這個scenario的入口點,其實是可以接受的方法。如果一個feature檔案中有多個scenario,也可以利用Cucumber的Background功能,統一把「Given I am on the invoice Web page」放在Background中,這樣就不用每一個scenario都重複描述。

    屏幕截图 2017-03-20 08.39.57

     

    如果覺得日後開發票功能可能會改成手機或桌機版本,到時候要把「Given I am on the invoice Web page」改成「Given I am on the invoice App screen」這樣很麻煩,也可以把這句改成更中性一點的敘述:「Given I am using the invoice function」,這樣子scenario要接Web、App、或桌上型應用軟體只要改step definition的內容就可以,不需修改feature檔案(不用改需求)。

    ***

    寫在Step Definition裡面

    ▼如果想維持原本的scenario敘述不變,但又想要透過UI來自動化這個scenario。

    屏幕截图 2017-03-20 08.29.10

     

    ▼第二種做法就是直接把連結到UI的程式碼寫在step definition裡面。這種做法的好處是scenario專心描述企業邏輯,當真的需要連結到UI的時候只需要修改step definition即可,不用動到scenario。

    屏幕截图 2017-03-20 08.51.01

     

    這種做法有兩個小缺點,首先從scenario檔案看不出每一個scenario的明顯「入口點」。第二個缺點是step definition內容變得有點亂,原本step definition是協助開發人員探索與定義系統實作的介面,現在夾雜了UI的自動化測試程式,很容易混淆原本的意圖。

    ***

    增加Support Layer

    ▼原本使用Cucumber的步驟由定義feature file開始,接著撰寫step definition,然後透過TDD的方式來完成domain object(production code)的設計與開發。因為step definition直接操作domain object,所以如果要加上透過UI來操作domain object就必須要修改step definition。

    屏幕截图 2017-03-20 08.09.40

     

    ▼為了讓step definition更乾淨,可以在step definition與domain object之間增加一個support layer(支援層),透過這一層來操作domain object。如此一來便可把UI的細節封裝在support layer。

    屏幕截图 2017-03-20 09.04.43

     

    ▼原本step definition直接操作domain object,現在改成透過KnowsTheDomain類別來操作domain object。

    屏幕截图 2017-03-20 09.18.59

     

    KnowsTheDomain類別很簡單,只是把原本step definition直接操作domain object的程式碼封裝在這裡而已。

    屏幕截图 2017-03-20 09.17.02

     

    現在思考一下如何重構(refactor)讓我們可以輕鬆切換有UI和沒有UI的自動化驗收測試。在原本的domain object中,開發票的責任由InvoiceBuilder類別負責,只要能夠提供兩種InvoiceBuilder的實作,一種是原本的實作,另外一種是包含UI的實作,如此一來只要讓KnowTheDomain類別的getInvoiceBuilder函數可以依據設定傳回不同的InvoiceBuilder類別實作,就可以達到「輕鬆切換有UI和沒有UI的自動化驗收測試」的目的。這種做法不需要修改scenario,也不用動到step definition。

     

    ▼首先套用Extract Interface重構,把原本InvoiceBuilder類別的介面抽離出來。

    屏幕截图 2017-03-20 09.38.18

     

    ▼原本的InvoiceBuilder類別改名為InvoiceBuilderImpl,並且實作剛剛抽離出來的InvoiceBuilder介面

    屏幕截图 2017-03-20 09.40.31

     

    ▼新增WebInvoiceBuilder類別,讓它繼承InvoiceBuilderImpl。複寫issue函數,在開發票的時候打開瀏覽器連到開發票系統的網頁畫面,透過網頁完成開發票的動作。

    屏幕截图 2017-03-20 09.42.37

     

    ▼最後透過dependency injection容器(在此使用picocontainer),讀取設定檔來判斷要注入WebInvoiceBuilder類別實例還是InvoiceBuilderImpl類別實例。

    屏幕截图 2017-03-20 09.46.12

     

    ▼如果要透過網頁測試,在設定檔中加入這一行。

    屏幕截图 2017-03-20 09.49.35

     

    ▼執行驗收測試,首先連結到開發票網頁,自動輸入含稅金額與稅率,按下開發票按鈕。

    屏幕截图 2017-03-20 09.51.58

     

    ▼接著看到計算後的稅額和未稅金額。

    屏幕截图 2017-03-20 09.51.35

     

    ▼當然驗收測試也是通過的。

    屏幕截图 2017-03-20 09.52.26

    ***

    結論

    今天介紹三種scenario串接UI的方法,各有其優缺點。第三種方法看起來最漂亮,但需要花多點設計與重構的功夫。如果鄉民們想要使用第三種方法但覺得scenario裡面沒有敘述功能起始點怪怪的,也可以結合第一種和第三種方法,把功能起始點描述在feature檔的Background裡面,scenario連結UI的實作方式則是用第三種方法來完成,這樣子應該就接近完美了XD。

    ***

    友藏內心獨白:什麼接近完美,明明就很麻煩…Orz。