l

2013年2月28日 星期四

用模式分析問題

Feb. 27 11:30~13:35

螢幕快照 2013-02-27 下午12.43.07

前幾天回實驗室跟學弟討論他的碩士論文,學弟已經事先針對他所準備做的題目寫了一個problem statement(一個段落的句子,用來描述論文所要解決的是什麼問題)。針對碩士論文要研究的問題寫一段problem statement是實驗室行之有年的方法,Teddy當場把學弟寫的problem statement讀了一次,第一個反應是:

怎麼沒有這個問題的context diagram(描述問題發生點的地形地物)?

學弟:ㄟ,沒有畫目瞪口呆

好,沒畫context diagram沒關係,Teddy在仔細把problem statement多讀幾次並當面討論之後,還是不太了解學弟要解決的問題,以及他所提出的解決方案。此時Teddy突然想到之前在上「Design Patterns這樣學就會了:入門實作班」的時候,Teddy有教學員們用pattern(模式)來做為問題分析與思考工具的方法,於是Teddy當場幫Teddy的研究題目用pattern的格式寫出第一個版本的描述:

版本一

Problem:如何確認一個Web應用系統在不同作業系統、不同瀏覽器中的行為是一致的?

Solution:提供一個快速建置測試環境的方法?

***

Teddy:請問這是你的碩士論文所要解決的問題以及你提出的解決方法嗎?

學弟:好像是…嗎疑惑

Teddy:可是上面這個solution和problem感覺對應不起來耶。提供一個快速建置環境的方法,並無法確認Web應用系統在跨平台環境下行為的一致性。要確認行為的一致性,至少應該要透過執行驗收測試來確認。

學弟:對啊。

Teddy:那你提供的方法有包含撰寫驗收測試這一塊嗎?

學弟:沒有耶。

Teddy:所以上面個problem-solution應該要加以修正,可能是problem寫錯了、solution寫錯了、或是兩者都錯挑眉質疑

Teddy:所以你想要解決的問題到底是什麼呢?

版本二

Context:由於網際網路與雲端計算的發達,許多商業與企業應用系統逐漸朝向Web應用發展。Web應用系統執行與瀏覽器之上,理論上只要瀏覽器支援WWW各種標準,便可達到跨平台的目的。但實際上各個瀏覽器對於WWW各種標準的支援程度並不相同,因此經常發生相同Web應用系統在不同瀏覽器上有著不同的行為,甚至造成功能錯誤。

因此,在產品釋出之前,Web應用系統應該在其所支援的所有跨平台環境中逐一測試。但要在不同的平台建置Web應用系統驗收測試環境經常需要耗費不少的人力,在時程緊迫之下,降低開發團隊落實跨平台驗收測試的動機。

Problem:如何快速建置一個跨平台Web應用系統的驗收測試環境?

Solution:(ToDo)

***

Teddy:把版本一的problem稍微改一下變成版本二的context,這個版本的problem是不是你要解決的問題?

學弟:對耶。

Teddy:所以你沒有要談如何撰寫驗收測試?

學弟:對,我假設驗收測試已經存在了,我要討論的問題是如何快速部屬跨平台驗收測試的環境,讓這些驗收測試可以在不同平台中順利執行。

Teddy:OK,那solution的部分就是你碩士論文要完成的工作。

學弟:我還有一個問題,如果我要限定驗收測試是採用RobotFramework撰寫,那件事要寫在Force嗎?

Teddy:目前看來,寫在Force或是Context應該都可以。等你的solution比較成形之後,我們再來看看要擺哪裡比較好。

***

友藏內心獨白:養成習慣之後,用pattern格式分析問題還蠻好用的很棒

2013年2月27日 星期三

有經驗的測試人員

Feb. 26 23:05~23:47

image

昨天晚上失眠一直到今天凌晨三點多才睡著,今天又上了一整天的課。更慘的還在後面,明天一整天要參加三個不同的會議,所以雖然現在很累了但是還是要先把明天的部落格給拚完,不然明天也抽不出時間寫啊挑眉質疑

剛剛在Facebook看到某位朋友分享的一個影片連結,介紹exploratory test觀念以及某個可以支援exploratory test的工具。影片中講者強調:

  1. Exploratory test是一種黑箱測試。
  2. 只要找到有經驗的測試人員,就可以「事先不需要花時間寫測試案例,便可以找出很多bug」。
  3. 某超強的工具可以很方便的用錄製的方式幫助這位有經驗的測試人員輕鬆完成exploratory test,並可透過工具將測試過程所找到的bug直接記錄下來,而且也可以自動產生測試步驟,測試人員只需要自己填寫每個測試步驟的expected result。
  4. 在影片中講者舉了一個例子,這位有經驗的測試人員操作某支程式,透過程式的GUI介面發現到這個程式對於輸入條件沒有判斷邊界值。接著這位有經驗的測試人員就使用某超強的工具把測試過程與bug report都產生出來。

Teddy對exploratory test並沒有研究,很認真的把影片看完之後,得到三個心得:

  • 如果影片中所敘述的測試方法就是exploratory test,那這種類型的測試Teddy在帶案子的時候幾乎天天都在做啊。
  • 看到工具的示範,覺得如果在做exploratory test的時候如果有工具可以輔助回報bug與把測試步驟記錄下來是還蠻不錯的。不過,這樣的工具和傳統的capture-replay的差別好像不大。
  • 最後一點,也是最重要的一點,在影片中好像把exploratory test捧上天,覺得這種方法可以找到很多其他測試方法無法找出的bug。依據影片中的說法,exploratory test需要由有經驗的測試人員來執行才會有很好的成效。但Teddy覺得,只要找到有經驗的測試人員,不管用哪種方法,都可以比起沒經驗的人找到多出很多、很多的bug。重點在於,這種有經驗的測試人員很難找啊。

***

結論,有經驗的測試人員重於超酷炫的測試工具,這一句可以加在「搞笑測試宣言」裡面…XD。啊,不行,敏捷宣言裡面已經有了:「個人與互動 重於 流程與工具 」。

***

友藏內心獨白:不要問影片的連結在哪裡啊。

2013年2月26日 星期二

要不要幫Private Method寫單元測試?

Feb. 25 20:09~22:17

image

很多有在寫單元測試的鄉民們都會遇到一個問題:「到底要不要幫private method寫單元測試?」關於這個問題反對與贊成的人都有各自的道理。

鄉民們的看法

反對者:Private method一定會被某個public method呼叫,我們只要測試public method等於也測了private method,所以不需要針對private method寫測試。而且從資訊隱藏的角度來看,private method之所以是「private」,就表示不希望被外界的人看到。從測試的角度來看,test case也是待測程式的「外人」,所以不應該看的見private method。既然看不見,就更談不上要幫private method寫測試了。

贊成者:Private method也有程式實作邏輯,既然有邏輯就應該要被測試。雖然可以透過public method測試到private method,但是要用這種方式來涵蓋private method的各種執行路徑則測試案例將會變得很複雜,也不容易撰寫。更何況「單元測試」原本就是一種「白箱測試」,也就是測試者是在可以看到待測程式原始碼的前提之下所寫出的測試案例。從測試者可以「看到待測程式原始碼」的這個角度來看,private當然也應該測試啊,這和資訊隱藏並不違背。

JUnit Recipes怎麼說

聽起來雙方都各有各自的道理,說實話Teddy也不確定哪一種方式比較好。以前Teddy的習慣,如果private method的邏輯有點小複雜的話,是會幫private method寫單元測試的。前一陣子Teddy為了準備3月份「單元測試與持續整合實作班」的教材,重新翻閱了《JUnit Recipes》這本2005年出版的「老書」,書中提到是否須測試private method的看法,Teddy覺得寫的不錯,節錄出來給鄉民們參考。

基本上這本書是認為不要幫private method寫測試,一旦鄉民們覺得要幫private method寫測試程式,也就表示這個private method不僅僅是扮演著helper method的角色。換句話說,這個private method的邏輯可能蠻複雜的,複雜到鄉民們覺得不對它單獨測試會過意不去。因此書中認為鄉民們應該考慮將這個private method抽離出來,放到另一個class中成為public method。此外,這種作法還可以符合「Single Responsibility Principle」。

看一個例子

今天Teddy看到一個「前人」所寫例子,剛好可以用來解釋上述概念。請參考下圖,假設鄉民們要設計一個ATM(提款機程式),這個ATM程式有一個類別叫做Account,用來代表一個用戶的帳戶。這個Account有一個withdraw() method,可透過它來提款。為了防止詐騙集團,提款程式規定每天提款上限為3萬元。withdraw()有兩個參數,第一個參數是提款金額,第二個參數是提款日期。

螢幕快照 2013-02-25 下午9.28.48

 

以下是withdraw()的程式碼,它透過exceedDailyLimit()這個private method來判斷本日提款金額是否已達上限,若已達上限則不讓使用者提款,並傳回false。

螢幕快照 2013-02-25 下午9.35.48

 

接下來是exceedDailyLimit()這個private method的程式碼,它透過另一個private method:getWithdrawAmountOfDate()來得到本日已提款的總金額。

螢幕快照 2013-02-25 下午9.37.49

 

接著再繼續看getWithdrawAmountOfDate()的程式碼,這裡面的邏輯就有點複雜了,不單獨對它測試有點對不起自己的良心啊挑眉質疑

螢幕快照 2013-02-25 下午9.40.26

***

應該要重構…嗎?

看完上面這個例子,再思考一下《JUnit Recipes》書中的講法,似乎真的應該把exceedDailyLimit()與getWithdrawAmountOfDate()抽離出來放到另外一個類別中,並且變成public mehtod,這樣似乎可以減輕Account類別的責任。

不過,剛剛Teddy跟Kay討論這個問題的時候,她插了一句話。

Kay:可是有些private method只是做一些輔助的計算,只有它所屬的這個類別會用到,如果把這些private method抽離到另外一個類別,那就會出現很多小的類別,但是很可能都只包含一根手指就數的完的method個數。

是啊,OO(物件導向)技術用到某種程度,有時就是會出現數量眾多的小型類別,但好處是類別之間的互動關係與程式結構變得比較清楚,程式也比較容易維護與測試。

***

最後為了Teddy的食、衣、住、行、育、樂,忍不住置入性行銷一下熱戀。欲知更多單元測試與持續整合技巧,歡迎參加3月23~24所舉辦的「單元測試與持續整合實作班」,3月11日前報名早鳥優惠中

螢幕快照 2013-02-25 下午9.58.22

***

友藏內心獨白:容易測試的程式通常設計也做得比較好。

2013年2月25日 星期一

[工商服務]泰迪軟體課程異動通知

Feb. 24 23:16~23:58

Scrum四月份加開班次

螢幕快照 2013-02-23 下午6.28.43

不知道是過完農曆新年鄉民們拿了壓歲錢還是立下新年新希望,3月9、10日舉辦的「Scrum敏捷方法實作班:第五梯次」居然在早鳥期限結束之前就已經報名額滿了,這可是開天闢地以來的頭一回。在額滿之後還有鄉民們來信詢問是否可以「加掛車廂」,但因為礙於場地大小限制並且考慮到上課品質,實在無法再增加名額(Teddy內心獨白:我也想一班塞很多人啊不要告訴別人)。因此Teddy特別在4月13~14日加開一次「Scrum敏捷方法實作班:第六梯次」,有需要的鄉民們請自行服用。

***

Design Patterns平日班確定開課

螢幕快照 2013-02-23 下午11.06.49

3月12、19、26日連續三個禮拜二舉辦的「Design Patterns這樣學就會了:入門實作班」確定開課。今年年初Teddy在規劃2013年度課程的時候,原本是沒有安排Design Patterns平日班,但陸續有兩位朋友跟Teddy反應:「我想上這門課,但是假日需要陪老婆、小孩出去玩,所以是否可以開平日班的課程?」針對這位好丈夫&好爸爸的要求,Teddy當然是無法拒絕,所以就在3月份安排了一次平日班課程。

看到這邊鄉民們可能會問:為什麼泰迪軟體大部分的課都是假日班?因為Teddy的客群大部分都是自費學員比較多,如果課程開在平日,學員們不但自費還要請假來上課,所以報名的意願就低了很多。否則Teddy自己是比較喜歡上平日班的課,因為假日Teddy也想要跟Kay一起出去玩啊熱戀

如果沒意外這應該是Teddy今年度唯一一次開在平日的「Design Patterns這樣學就會了:入門實作班 」(平日班招生不容易啊),早鳥優惠2/26日截止,有需要的鄉民們可以參考一下。

***

例外處理設計與重構開課時間調整

「例外處理設計與重構實作班」這門課原本Teddy規劃一天的課程,但因為課程內容蠻豐富的,最近Teddy還在掙扎到底要上一天還是兩天(迷之音:真相只有一個,那就是Teddy太愛碎碎念了,一天恐怕不夠用挑眉質疑)。所以在「2013年課表」網頁所公布的「例外處理設計與重構實作班」的開課日期目前只是暫定的日期,等課程天數決定之後Teddy會再公布最後的開課日期。

***

友藏內心獨白:希望今年能有更多的鄉民有機會可以學習Scrum。

2013年2月24日 星期日

2009北越跟團之旅Day4-A陸龍灣(上)

Feb. 23 23:44~Feb. 24 00:16

今天離開胡志明市來到車程約三小時的陸龍灣,據說等一下會去搭小船。到達目的地之後先到某間古色古香的廟宇參觀,看到廟宇牌匾上的中文字就知道這一定是古蹟啦。

螢幕快照 2013-02-23 下午11.46.20

螢幕快照 2013-02-23 下午11.46.48

 

這附近的山和下龍灣很相似,只是一個在海上,另一個在陸上。

螢幕快照 2013-02-23 下午11.47.00

螢幕快照 2013-02-23 下午11.47.12

 

古人的題字。

螢幕快照 2013-02-23 下午11.47.35

螢幕快照 2013-02-23 下午11.47.58

 

廟中供奉的神明。

螢幕快照 2013-02-23 下午11.48.08

 

離開廟宇之後來到本日的主打行程,搭小船遊下龍灣,真的是好多小船啊。

螢幕快照 2013-02-23 下午11.49.18

 

出發了,從這邊看覺得景色沒有特別美,但越往裡走越漂亮。

螢幕快照 2013-02-23 下午11.49.39

螢幕快照 2013-02-23 下午11.50.09

螢幕快照 2013-02-23 下午11.50.56

 

用腳划船也是這裡的特色之一喔很棒

螢幕快照 2013-02-23 下午11.51.21

 

過橋了,小心頭不要撞到了。

螢幕快照 2013-02-23 下午11.51.34

 

照片中水面上的綠色植物請鄉民們猜一下是什麼?

螢幕快照 2013-02-23 下午11.52.03

 

答案揭曉,居然是水稻耶。

螢幕快照 2013-02-23 下午11.52.27

 

還有人養羊。

螢幕快照 2013-02-23 下午11.52.54

 

繼續往裡面走。

螢幕快照 2013-02-23 下午11.54.27

螢幕快照 2013-02-23 下午11.54.59

 

要穿過山洞…這算山洞嗎?

螢幕快照 2013-02-23 下午11.55.36

 

古人當然不會放過這裡,題字是一定要的啦。

螢幕快照 2013-02-23 下午11.55.45

 

要出山洞了。

螢幕快照 2013-02-23 下午11.56.38

照片很多,下回待續。

***

友藏內心獨白:此行最好玩的景點就是陸龍灣的啦。

2013年2月23日 星期六

2009北越跟團之旅Day3-B胡志明故居

Feb. 22 17:58~18:34

離開胡志明廣場之後來到旁邊的胡志明故居,首先看到主席府,這裡是接見外賓的場所。

螢幕快照 2013-02-22 下午6.07.56

 

這兩個建築物忘了哪一個才是胡志明住所,還是兩個都是?!

螢幕快照 2013-02-22 下午6.09.57

螢幕快照 2013-02-22 下午6.24.05

高腳屋內一角。

螢幕快照 2013-02-22 下午6.10.20

螢幕快照 2013-02-22 下午6.10.11

 

另外一個建築物內部照片。

螢幕快照 2013-02-22 下午6.09.22

 

屋外有一個池塘,據說胡志明經常在此餵魚。

螢幕快照 2013-02-22 下午6.10.55

 

這裡有一個很有趣的小廟,叫做一柱廟,蓋在一根柱子上面的廟宇。

螢幕快照 2013-02-22 下午6.11.18

螢幕快照 2013-02-22 下午6.11.37

離開胡志明故居之後到市區搭人力車遊街。

螢幕快照 2013-02-22 下午6.12.22

螢幕快照 2013-02-22 下午6.12.46

螢幕快照 2013-02-22 下午6.12.59

螢幕快照 2013-02-22 下午6.29.22

螢幕快照 2013-02-22 下午6.30.31

螢幕快照 2013-02-22 下午6.31.00

 

印象中之後有去看水木偶,不過不能拍照,所以沒圖沒真相挑眉質疑

***

友藏內心獨白:本日行程有點小無聊啊。