l

2014年9月27日 星期六

2014京都考察之旅Day7-F高台寺夜櫻

Sep. 13 21:05~21:30

離開建仁寺之後徒步走到附近有點遠又不會太遠的高台寺賞夜櫻,一路上夜色昏暗,搭配黃色的路燈別有一番風味。

螢幕截圖 2014-09-13 21.08.35螢幕截圖 2014-09-13 21.09.07螢幕截圖 2014-09-13 21.09.20螢幕截圖 2014-09-13 21.09.55螢幕截圖 2014-09-13 21.10.14螢幕截圖 2014-09-13 21.10.27螢幕截圖 2014-09-13 21.10.37螢幕截圖 2014-09-13 21.10.57螢幕截圖 2014-09-13 21.11.13螢幕截圖 2014-09-13 21.11.22螢幕截圖 2014-09-13 21.11.33螢幕截圖 2014-09-13 21.11.48

 

買票進入高台寺,寺內還蠻大的,不過因為燈光昏暗,無法一窺全貌。其實沒看到什麼櫻花挑眉質疑,倒是欣賞了一場燈光秀。高台寺中有一片高大的竹林,夜晚打光之後走過竹林非常舒服,有一種身處深山隱居的錯覺。

螢幕截圖 2014-09-13 21.25.43螢幕截圖 2014-09-13 21.26.18螢幕截圖 2014-09-13 21.26.26螢幕截圖 2014-09-13 21.26.33螢幕截圖 2014-09-13 21.26.42螢幕截圖 2014-09-13 21.28.58螢幕截圖 2014-09-13 21.26.56螢幕截圖 2014-09-13 21.28.30螢幕截圖 2014-09-13 21.28.39螢幕截圖 2014-09-13 21.29.22螢幕截圖 2014-09-13 21.29.42螢幕截圖 2014-09-13 21.30.09螢幕截圖 2014-09-13 21.30.19螢幕截圖 2014-09-13 21.30.31螢幕截圖 2014-09-13 21.30.49螢幕截圖 2014-09-13 21.31.00螢幕截圖 2014-09-13 21.31.56螢幕截圖 2014-09-13 21.32.33螢幕截圖 2014-09-13 21.32.10螢幕截圖 2014-09-13 21.32.22螢幕截圖 2014-09-13 21.32.43

螢幕截圖 2014-09-13 21.42.01螢幕截圖 2014-09-13 21.42.55螢幕截圖 2014-09-13 21.43.06

***

友藏內心獨白:終於結束本日行程。

2014年9月26日 星期五

Test Double(2):五種替身簡介

Sep. 22 17:09~19:42

螢幕截圖 2014-09-22 17.12.08

 

依據《xUnit Test Patterns》的解釋,五種Test Double的含意如上圖所示。不過讀完之後還是有點小疑惑,如果再配合MSDN Magazine上面的這張圖,就更容易理解了。

螢幕截圖 2014-09-22 17.19.44

 

從Test Double與本尊之間的功能相似度來區分,Dummy Object根本沒有實作,是「假到非常假」的替身。Stub有實作,但是其實作方式通常採用寫死某個特定回傳值的方式。Spy和Stub類似也都有實作,但是Stub用來應付「state verification」(狀態驗證),而Spy則是用來應付「behavior verification」」(行為驗證)。Spy會記錄SUT與DOC之間的行為互動,例如在上一集所提到的Observer設計模式,如果要測試Subject與Observer之間的互動,就可以用Spy技術來替代Observer。Fake則是與本尊行為非常接近的替身,差別在於Fake採用比較簡單的方式來實作本尊的功能。例如,本尊是SQL Server,而測試的時候為了速度考量,使用HSQL這個in-memory的資料庫來做為替身。

最後一種Test Double是Mock Object,從上圖來看,Mock技術可以做到Dummy、Stub、Spy的功能,但比較無法做到Fake。簡單的說,Mock技術可以藉由Mock Object Library自動產生Dummy、Stub或Spy這三種Test Double,而不需要開發人員自己動手寫。

***

接下來的幾集將以一個應用Command模式的監控程式為例子,說明應用這五種Test Double的測試技巧。

***

友藏內心獨白:Mock是一種自動產生Test Double的技術。

2014年9月25日 星期四

Test Double(1):什麼是測試替身?

Sep. 22 15:37~16:56

螢幕截圖 2014-09-22 16.49.01

 

10月初又到了Teddy一年兩次的出國考察時間,每次出國前Teddy都很頭痛,因為除了原本每天一篇文章以外,還要事先把出國這段時間的部落格文章寫好。九月份的周末Teddy都在上課,加上學校開學,又要花時間備課,就更沒有時間寫文章。剛剛看了一下行事曆,有種部落格快要開天窗的危機感不要告訴別人

想來想去,乾脆把上課的教材拿來講好了。這一系列7篇文章將連載在「單元測試與持續整合實作班」所介紹五種Test Double技巧。今天先說明Test Double(測試替身)

在正式介紹Test Double之前,Teddy要談一下和它的一段「緣分」。話說2004年Teddy和Kay去美國參加PLoP(Pattern Languages of Programs)研討會發表Teddy所整理的幾個e-learning patterns。研討會採用小組討論的方式進行(Writer’s Workshop),Teddy這一組有一個英國人,他發表的patterns裡面,其中有一個就是Test Double。2007《xUnit Test Patterns》這本書出版,Teddy赫然發現原來作者就是當時和Teddy同一組的Gerard Meszaros。沒想到Meszaros居然持續耕耘他的測試模式,最後還整理出版了一本八百多頁的書,真的不容易。

***

測試術語

在介紹Test Double之前先介紹兩個測試常用術語:

  • SUT:System Under Test或Software Under Test的簡寫,代表待測程式。如果是單元測試,SUT就是一個function或method。
  • DOC:Depended-on Component(相依元件),又稱為Collaborator(合作者)。DOC是SUT執行的時候會使用到的元件。例如,有一個函數X如果執行失敗會寄送email,則email元件就是函數X的DOC。

在做單元測試的時候,測試對象是SUT,但因為SUT會呼叫其他物件,使得SUT相依於DOC。換句話說,要測試SUT,DOC也必須存在,這使得測試變得更複雜。例如,請參考下圖的Observer設計模式,假設鄉民們要測試Subject的notify函數,因此Subject的notify函數是SUT,Observer是DOC(因為notify函數會呼叫Observer的update函數)。notify函數所影響的對象是Observer,透過測試notify無法直接觀察到Observer的update函數是否有真的被呼叫,這樣的相依性使得測試notify變得困難。

image

  ***

解決什麼問題

在《xUnit Test Patterns》書中提到Test Double可以解決兩個常見的測試問題:

  • 如何單獨驗證SUT的邏輯而不用真的使用到DOC?
  • 如何避免測試執行太慢?

以Observer設計模式為例,如果鄉民們可以用一個替身來代表真正的DOC(Observer),那麼就可以在這個替身上面動手腳,讓測試變得更簡單。此外,因為替身不是本尊,所以執行速度可以非常快,因此可以解決測試案例執行太慢的問題。

***

Test Double是一種讓SUT可以不依靠DOC而單獨被測試的作法,在實作上有五種Test Double,分別是Dummy Object、Test Stub、Test Spy、Fake Object與Mock Object,之後將一一為鄉民們介紹。

***

友藏內心獨白:替身也是有區分很多種的。

2014年9月24日 星期三

[還少一本書] 絕不是靠運氣:創造事業與人生的雙贏

Sep. 10 08:38~09:55

螢幕截圖 2014-09-10 23.28.47

 

絕不是靠運氣:創造事業與人生的雙贏》(It’s Not Luck)的劇情延續上一本《目標:簡單有效的常識管理》,原本的主角廠長「羅哥」,因為成功套用限制理論拯救工廠,因而被優尼公司(UniCo)拔擢成為集團的執行副總,負責管理好幾間工廠。

優尼公司原本採用多角化經營的策略,旗下有不同領域的工廠。但在某次董事會後,公司策略轉變,要求賣掉非核心的事業體以求套現。而這個要被賣掉的非核心事業體,正是主角羅哥所負責的部門。羅哥無法扭轉董事會的決定,只能再度想辦法讓事業體的子公司在被賣掉之前,可以在短時間內大幅提高獲利,以避免出售之後子公司被解體的命運。

《絕不是靠運氣》還是繼續沿用限制理論來協助子公司,但書中增加了衝突圖未來圖等新的工具,希望能夠化衝突為雙贏。假設兩造雙方產生衝突,衝突圖的概念是先找出雙方共同目標,然後寫出雙方各自為了達成這個共同目標所採取的策略。最後,基於這項策略,雙方各自做了什麼會造成衝突的決定,然後試圖找出一個雙方都可接受的方法,來解決衝突。

螢幕截圖 2014-09-10 09.01.39

書中第14頁的衝突圖例子。

 

這本書比前一本的581頁要薄很多,只有364頁。以下節錄書中幾句Teddy覺得寫的很有道理的話。

  • 比批評更惱人的就是建設性的批評(p. 41)。
    • 如果是單純的謾罵不理對方也就算了,但是一針見血有道理的批評,卻讓人又痛又無法忽視。
  • 決定緩衝存量的因素有兩個:預期的消耗量,及預期的補貨時間。(p. 57)。
  • …我們只需要清楚地陳述負面的因果,而不提出解答…如果是我提出建議,他頂多會把我的建議當成具侮辱性的、不公平的要求(p. 79)。
    • 在解決衝突的時候,嘗試列出發生衝突的負面因素,並建立起產生這些因素的因果關係。讓衝突雙方經過溝通自行找出可能的解決方案。
  • 這套技巧(衝突圖)主張你不應該試圖找出妥協,它主張要檢視箭頭後(衝突點)的假設,以化解衝突(p. 109)。
  • 在我的公司中,我希望產品毛利不是接受訂單與否的必要條件之一。接受訂單與否,該考慮的只有訂單對整體產量及整體有效產出的影響(p. 207)。
  • 從供應商的角度來看,產品就是實質的產品,這個觀點只能容許有限的改善。若以市場的觀點來看,你就會發覺,對產品的看法寬廣許多,包含了相關的服務、財務條件、保證等等。產品包含了整套交易(p. 216)。
  • 真正決定市場眼中的產品價值,不是我們如何生產,而是買家能從使用產品中得到的好處(p. 217)。

***

這本書比較有趣的新觀念就是建構衝突圖,以及如何從衝突圖之中找出雙方都可以接受的雙贏方案。看起來好像很簡單,但是必須要有相當的練習經驗,才有可能應用自如。

***

友藏內心獨白:一次處理三家公司,還真忙啊。

2014年9月23日 星期二

[還少一本書] 目標:簡單有效的常識管理

Sep. 09 21:41~23:15

螢幕截圖 2014-09-09 21.48.59

 

又有一陣子沒有推薦 毒物 讀物給鄉民們,這次要分四次介紹「高德拉特」(Eliyahu M. Goldratt)的四本書,今天先介紹《目標:簡單有效的常識管理》(The Goal: A Process of Ongoing Improvement)。

高德拉特是一位以色列物理學家,他提出了限制理論(Theory of Constraints, TOC),期望用少數簡單的假設,來解釋複雜且廣泛的產業現象。為了解釋限制理論,他寫了四本小說(沒錯,小說),用說故事的方式讓鄉民們容易理解艱深的理論。

「天下文化」出本了這四本書的中文版,並將其歸類在「企管財經」類。原本Teddy很少讀這類的書,但在研究看板方法與精實開發的時候,發現許多人都提到限制理論與《The Goal: A Process of Ongoing Improvement》這本書,所以就乾脆把這四本全部買回來讀一次。讀完之後還蠻有趣的,覺得對看板方法的理解,又更深入一些。

這本書描述身為廠長的主角「羅哥」,管理一間虧損累累且即將倒閉工廠的故事。原本一籌莫展的羅哥,經由物理學教授「鐘納」的指點,套用了限制理論(書中翻譯成「制約法」),在短短的三個月內讓工廠奇蹟似地起死回生的故事(服用TOC的效果美好的有點像童話故事不要告訴別人)。

這本書的內容有581頁,以下節錄書中幾句Teddy覺得寫的很有道理的話。

  • 唯有透過推論的過程,我們才能真正地學習;直接把最後的結論擺在我們眼前,不是好的學習方式(p. 9)。
    • 這一點Teddy非常認同,在教學的時候,Teddy也是儘量用發問題的方式,讓學員們先思考與推論一下可能的答案。Teddy常說:「下課之後我不會跟你們回家,也不會到你們公司上班。希望大家上完課能培養自行餵食(自我解決問題)的能力。」
  • 除非你知道目標是什麼,否則你就無法了解生產力的真正意義。在你了解生產力的真正意義之前,你只不過是在玩一堆數字遊戲和文字遊戲罷了(p. 50)。
    • 很多人會覺得,員工很忙,在公司加班到很晚,就是好員工,就是有生產力的員工。錯!這些看起來很忙的員工,可能只是在產生更多的庫存而已,並非是真的有生產力。
  • 公司是否夠賺錢的三個重要指標:淨利、投資報酬率和現金流量(p. 75)。
  • 這套衡量指標一方面能充分表達出賺錢這個目標,另一方面也能讓你發展出工廠的基本營運規則。這套方法共有三個衡量指標,就是有效產出(throughput)、存貨(inventory)和營運費用(operational expense)(p. 92-93)。
    • 有效產出的定義很重要,書中的有效產出是指透過銷售所賣出的東西,而不是工廠生產出來的東西。如果生產一大堆東西卻賣不出去,一點用也沒有,這不是有效產出。
  • 表達目標的方式是:增加有效產出,但同時減少存貨和營運費用(p. 104)。
    • 以上目標對於軟體開發同樣適用,從敏捷開發的角度來看,採用value-driven的開發方式就是增加有效產出的手段,採用iteration開發方式與限制WIP則是減少存貨。至於減少營運費用,則是從重視品質,讓團隊成員立志成為專業的開發人員(請參考《Clean Code》與《Clean Coder》這兩本書)著手。
  • 有效產出是我們收進來的錢,存貨是目前積壓在系統中的錢,而營運費用則是為了讓有效產出能夠發生,我們必須付出去的錢(p. 114)。任何我們花掉的錢都是營運費用,任何我們可以藉銷售而回收的投資都算存貨(p. 118)。
    • 公司存在的目的就是獲利。從錢的角度來訂定指標,容易看出很多問題。
  • 每個人時時刻刻都在工作的工廠,是非常沒有效率的工廠(p. 132)。
    • 鄉民們的專案,是否也存在著上述的現象啊,每個人「看起來」都很忙,不過可能有很大一部分是在「瞎忙」。
  • 每個工廠都並存著兩個現象。一個現象就是所謂的「依存關係」(dependent events)…一個事件(例如作業程序)或一系列的事件必須等待其他事件發生之後,才能發生,也就是必須有賴前一個事件發生之後,接下來的事件才會依序發生(p. 138)。…當這些相關事件都和另外一個叫「統計波動」(statistical fluctuations)的現象結合起來時,事情就變大了(p. 139)。
    • 不管是專案管理還是軟體開發,相依性一直是造成系統複雜度的主因。
  • 我們不能單獨衡量某個資源的產能。真正的產能完全要看它在工廠流程中的位置而定(p. 220)。
    • 和精實開發強調關注全域(系統性思考)而非局部最佳化有異曲同工之妙。
  • 瓶頸不一定很壞,或很好,瓶頸只是你們所面對的現象罷了。…找到瓶頸在哪裡之後,你們必須利用瓶頸來控制通過系統和進入市場的流量罷了(p. 223)。
    • 瓶頸是一種限制,有限制不一定是壞處,要看組織如何利用這個限制。利用的好,可能只要付出有限資源,便可獲得極大的利益。

***

這本書還有很多有趣的內容,上面的引用已經夠多了,建議鄉民們買一本回家看。最後,把書中關限制理論的五步驟聚焦法列出來讓鄉民參考:

  1. 找出系統的瓶頸。
  2. 決定如何利用瓶頸。
  3. 根據上述的決定,調整其他的一切。
  4. 把系統的瓶頸鬆綁。
  5. 假如步驟4打破了原有的瓶頸,那麼就回到步驟1。

***

友藏內心獨白:中文書名的副標題沒有反應出原文書中的A Process of Ongoing Improvement這個重點啊。

2014年9月22日 星期一

專業程式設計師怎麼做?(下)

Sep. 10 20:45~22:02

image

 

這一系列的最後一集,繼續介紹Bob大叔在《The Clean Coder》書中提到對於專業人士的建議。

 

做完的定義

每個開發人員心目中都有一份對於「工作做完」的定義,有些人認為程式沒有語法錯誤就算做完,甚至不管功能是否正確;有些人會手動測試,好一點的會會加上幾個單元測試;再負責任一點的,會請同事幫忙檢視程式碼。

Bob大叔任文專業人士的做完只有一個定義,就是做完表示程式碼完成並且可以通過所有的測試,QA和需求方也都已經認可。翻成白話文就是說:「產出可釋出品質的軟體才叫做完。」

這樣的高標準,的確是需要花費一番功夫方可達成。誰叫鄉民們是「專業人士」呢…是嗎?

 

整合失敗是一種Bug

有些團隊雖然實施「持續整合」(continuous integration;CI),但CI系統上經常有許多測試案例是無法通過的情況。不專業的團隊,會忽視建構失敗的警訊,將其視為惱人的噪音,或是歸因於「運氣不好」,錯誤下次應該會自動消失。久而久之,CI上可通過的測試案例越來越少,原本依靠CI所建構出的安全網也完全破功。沒有自動化測試與持續整合系統的幫助,軟體再度變成硬體,每次修改都帶來無止境的痛苦。

當CI系統上的專案建構失敗時,團隊成員應該立即停下手邊工作,一起排除問題。這個觀念Teddy覺得應該是從TPS的「安燈」作法而來,一旦代表問題的燈號亮起,生產線停止運轉,提高大家對於品質的重視。待問題排除之後,才可以恢復生產線運轉。

 

程式碼共享

不專業的程式設計師會將「自己」的程式碼鎖在保險箱中,不讓別人看見。自然地,他也不想去看別人的程式碼。程式碼不是地盤,程式設計師也不是黑道或小混混,不應在程式碼中畫地自限,阻擾知識的流通和讓更多雙眼睛一起幫忙找出問題的機會。

如果程式設計師只負責特定的程式碼,很可能會造成重複程式碼(duplicated code),當有人形成瓶頸的時候無人可幫助,例如短時間湧入大量工作、遇到無法克服的技術問題、對於一再重複相同的工作感到無趣、耍大牌、生病、請假、離職。

所以,Bob大叔認為專業人士應該採用XP的collective ownership(集體擁有權)實務做法,打破程式碼所有權之間的「派系之分」,程式碼的所有權應該屬於「整個團隊」所共有。

 

持續產品開發團隊

很多公司在執行專案的時候,採取以專案為主的方式來建構團隊。當專案成立的時候,到各個單位去拉人進來執行專案,每個人只在專案中停留短暫時間,甚至同時間屬於多個專案。待專案結束後這些人便歸建到原單位,因此很難培養默契。

Bob大叔說:「這是一種愚蠢的做法。」專業的開發組織會把專案交給已經具有默契且有凝聚力的團隊。這樣的團隊可以同時負責多個專案,團隊成員自我管理,依據各自的能力、意願、專長來分配工作,而且會順利完成所負擔的工作。

雖然Bob大叔沒有明講,但他在書中所敘述的團隊,就是Scrum團隊所具備的三點特性。

  • 跨職能團隊。
  • 自我管理。
  • 持續產品開發模式(維持有默契的團隊來完成各種專案)。

鄉親們,你們的團隊是屬於哪一種呢?

***

友藏內心獨白:Bob大叔的專業人士基本是就是敏捷開發人員啊。

2014年9月21日 星期日

2014京都考察之旅Day7-E花見小路與建仁寺

Sep. 01 22:45~23:12

離開高野川之前在橋邊的咖啡廳吃了點東西。這裡視野還不錯,窗外看出去就是剛剛烏龜跳石的地方。天空上看到好幾隻老鷹,還有為數眾多的烏鴉在飛翔。

螢幕截圖 2014-09-01 22.47.45螢幕截圖 2014-09-01 22.47.55螢幕截圖 2014-09-01 22.48.09螢幕截圖 2014-09-01 22.48.23螢幕截圖 2014-09-01 22.48.45螢幕截圖 2014-09-01 22.48.53

 

離開高野川之後傍晚五點半左右來到四條河源町。這附近是京都非常熱鬧的地方,人潮川流不息。

螢幕截圖 2014-09-01 22.51.47螢幕截圖 2014-09-01 22.51.55螢幕截圖 2014-09-01 22.52.18螢幕截圖 2014-09-01 22.52.40螢幕截圖 2014-09-01 22.52.46螢幕截圖 2014-09-01 22.53.00螢幕截圖 2014-09-01 22.53.11螢幕截圖 2014-09-01 22.53.24螢幕截圖 2014-09-01 22.53.32

 

走了一會,終於看到花見小路的指示牌。這裡是看藝妓表演的地方,道路兩旁有很多高級餐廳。原本想在這裡吃晚飯,看了價錢之後,大概是平常晚餐預算的兩倍價錢,當場放棄挑眉質疑

螢幕截圖 2014-09-01 22.57.46螢幕截圖 2014-09-01 22.58.13螢幕截圖 2014-09-01 22.58.27螢幕截圖 2014-09-01 22.58.40螢幕截圖 2014-09-01 22.58.53螢幕截圖 2014-09-01 22.59.04螢幕截圖 2014-09-01 22.59.18螢幕截圖 2014-09-01 22.59.39螢幕截圖 2014-09-01 23.00.07

 

繼續往前走來到建仁寺,夕陽的餘暉照在雲朵上,作為寺廟與櫻花的背景,令人非常難忘的一幕。

螢幕截圖 2014-09-01 23.04.10螢幕截圖 2014-09-01 23.04.18螢幕截圖 2014-09-01 23.04.29螢幕截圖 2014-09-01 23.06.26螢幕截圖 2014-09-01 23.06.37螢幕截圖 2014-09-01 23.06.45螢幕截圖 2014-09-01 23.06.57螢幕截圖 2014-09-01 23.07.07螢幕截圖 2014-09-01 23.07.19螢幕截圖 2014-09-01 23.07.53螢幕截圖 2014-09-01 23.08.02螢幕截圖 2014-09-01 23.08.15螢幕截圖 2014-09-01 23.07.32

***

友藏內心獨白:沒想到這裡居然有一間那麼大的寺廟啊。