2015-05-27

[瀑布底下玩SCRUM] 即將導入 Continuous Delivery 的心境

[不 要 覺 得 目 前 沒 有 用 就 不 學 了]

前一陣子想在公司開Unit Testing的Study Group
結果人數不夠開不成 我就趕緊找了另一個Group抱大腿
這個Group是在讀 Continuous Delivery
讀了幾個星期之後 發現可以導入部門改進目前遇到的一些問題

還真的機會來了 !!!

今天早上邀請了幾個相關的Developer跟QA
一起Brainstorming大家要怎麼去做Continuous Delivery

在諾大的白板上用mind map的方式圈起了一大塊一大塊的Feature
就覺得遙遙無期的藍圖已經轉變成可以執行的Product Backlog了
頓時心中燃起了希望之火

對了!!

在白板上用mind map做planning 也是向其他Team偷學來的
JIRA Sharing 筆記

SCRUM Planning Meeting 是參加社群學來的

總之
不要覺得目前沒有用就不去學它
因為你不知道那天真的會用到喔~



2015-05-22

[心得] Improvement Kata工作坊 - 讓員工自己變優秀的解藥(之一)

2015.05.21
Improvement Kata工作坊 - 讓員工自己變優秀的解藥(之一)

今天的主題是講Improvement Kata

主要的重點在於 : 

1. 了解現況
2. 確定目標
3. 持續改進

改進的重點在於套用kata的套路 
持續練習固定的節奏與步驟來達成目標






























隨後玩的Workshop 總共三組數學題要玩3 run
1. 第一線員工計算三份數學題 (可用計算機)
2. 三份算好之後再交由Team Lead加總 (心算)
3. 副總確認內容無誤簽名負責
4. 總經理簽名

我們這組第一次run的結果是花了約143秒
接下來大會訂下一個目標 : 下次執行正確率需達60% 速度需快30%


於是大家就開始Brainstorming要如何改進
我們這組想到了以下方法:
1. 第一線員工幫Team Lead一次算好好, Team Lead只要簽名
2. 只寫兩份考券就好 (因為大會要求60%正確率 完成兩張考券的正確率是66%)
3. continuous delivery, 原本第一線員工要完成三張考券才能上傳,現在完成一張就上傳

結果我們省下了86%的時間 還仍保有100%正確率
還不賴

不過整個過程的重點應該在於
員工們要先發覺現況是有問題的
再來一起Brainstorming solution
再經過每一次的實驗 逐步改進
跟SCRUM 是不是很類似呢?

2015-05-21

[讀書筆記][小故事][制度殺人] 為什麼要導入SCRUM

[讀書筆記][小故事][制度殺人] 為什麼要導入SCRUM

在書上讀到了一則不有趣但是又發人深省的故事。
Milgram Experiment米爾格倫實驗
米爾格倫實驗(Milgram experiment),又稱權力服從研究(Obedience to Authority Study)是一個針對社會心理學非常知名的科學實驗。
這個實驗室要求受測者擔任老師的角色,教導另一間房間的學生(演員),老師與學生分處不同房間,彼此看不見對方,但是老師聽得見學生(演員)的聲音。
測試是這樣的,一旦學生答錯,老師會對學生執行電擊,而電擊的強度會越來越高。
當電擊伏特數提升到一個程度之後,學生會開始尖叫、敲牆壁、哭喊要退出實驗,最後突然保持沉默再也沒有反應了。
http://commons.wikimedia.org/wiki/File:Milgram_Experiment.png


當受測者表示希望暫停實驗來觀察學生的身體狀況時,實驗人員會告知他們不用承擔任何的責任,大多數的人都會繼續進行。

若是受測者表示想要停止實驗時,實驗人員會依以下順序這樣子回覆他:
1.     請繼續。
2.     這個實驗需要你繼續進行,請繼續。
3.     你繼續進行是必要的。
4.     你沒有選擇,你必須繼續。

當然,電擊是假的。但是幾乎所有的受測者都照做了,給予一個一直在尖叫的學生最後的電擊。

心得:
這些受測者是壞人嗎?並不是!
他們只是純粹聽命行事而已,對於他人並沒有敵意。
但是如果這個制度出了問題,這些沒有惡意的一群人同樣也會導致毀滅的結果。

對應到我們的職場上,我們也都是制度下的產物,而SCRUM的用意就在於先接受這個事實,透明地檢視出失敗的制度並給予修正,而非找一個戰犯來譴責!

資料來源:
SCRUM:用一半的時間做兩倍的事

2015-05-18

[心得文] 自動測試與TDD實務開發 Day1

[前情提要]
其實半年前我就想報名這堂課,不過可惜最後因為幾個負面思考而打消了念頭,當時在心中埋下了一顆悔恨的種子,告訴自己說,下次再有這個機會請不要錯過。
終於,今年盼到了第三梯的課程,雖然價格提高了4 =.= ,不過還是自己能夠負擔的範圍啦,當然就報囉。
剛好今年也給了自己一些明確的目標:
1.     2015Q4 要在公司教授Unit Testing的課程:
為了要教別人,所以先來觀摩大神91哥是怎麼教學員的XD
果然Lab中的幾個例子都很務實,也給了我一些方向。
2.     Team導入完整的Continuous Delivery Solution
為了使CD更完整,Unit Testing就不能缺席,我一定會建置出一個方便的Solution讓同事們能夠無痛升級。

於是呢,獲得老婆的諒解之後,踏上了學習之路!


[我們的痛?]
91在課程的一開始,先分組讓大家自我介紹,請大家分享一下為什麼要來上這堂課。我覺得這是個很好的開始,要解決任何問題之前,請先停下來思考:問題是什麼?釐清問題之後,大家的學習會更努力更有效率。
歸納當天學員們的問題,不外乎就是:
1.     想了解Unit Testing & TDD
2.     實務上怎麼導入?

以我自己為例,我為什麼想要學這堂課的原因是:
1.     我要導入Unit Testing至我們Team,希望能學到實務的例子,提供簡單的架構,降低同事們的學習門檻。
2.     我要教這堂Unit Testing,所以來學習91是如何教學員。

實務上開發常見的問題有那些呢?我想身為一個Developer,應該對這些問題都耳熟能詳,但是卻無法有效解決:

  • 測試環境無法準備
  • 不曉得Developer交付的code是否正確?
  • Side Effects
  • 跟其他Team一起平行開發中,過程中必須相互等待。

其實我們就能透過Unit Test解決上述問題。
1.     測試環境無法準備????
有些系統是屬於外部系統,他們的整合日期可能不是我們這個Team這個層級就能決定的,但是開發不能等他們好再來測,此時我們可以使用Mock Framework來協助我們克服這個問題。

2.     不曉得Developer交付的code是否正確?
交付code即附上Unit Test。結果清楚明瞭。未來若整合進CD,我們可以在建置後就能知道code是否正確,比起問題要到QA才發現還早多了。Bug是需要提早發現及早治療的。

3.     Side Effects
儘管有Code Review。大部分最難防的還是Side Effects吧!而完整的Unit Test就能幫大家補上這一塊,改完code隨時執行Unit Test。有沒有改東壞西馬上就知道結果。
遙想當初我想要Refactor某個Feature,卻因為沒有Unit Test,也沒有QA可以驗證而放棄。如果有Unit Test就會增加我們Developercode的自信心吧!

4.     跟其他Team一起平行開發中,過程中必須相互等待。
其實這問題跟第一點很像,但是更有可能以design的方式就能解決。體會到Unit Test的魅力之後,自然而然會想寫出可以測試的程式(Testability),在寫code時自然就會考量到Isolated關注點的問題,盡量將Dependency隔離開。最後的實務上就能以Mock Framework輕鬆隔離相依性,只測該測的地方,讓Unit Test變得簡單,簡單才會有人想用。

這條路上一定會被問到:
如果寫Unit Test,在開發上會增加多少時間?
這讓我想到之前讀”The Art of Unit Testing with Examples in .NET”這本書時,作者以他本身在大型企業的案例作為例子:





Developer開發的時間雖然變成2倍,但是整體的時間是下降的,更重要的是,Bug的數量很顯著的下降。這就是Unit Test的威力。

還有一句話讓我很有感:
面對未知的問題,不要用猜的,用測的最準!!!


[基礎概念]
什麼是Unit Test
幾點定義:
1.     最小的測試單位
2.     外部相依性為零
3.     沒有商業邏輯
4.     Test Case彼此的相依性為零
5.     一個Test Case一次只測一件事

其中最重要的兩點就是 2 & 5
只要把握這些特性,就能寫出有效的Unit Test
如果Test Case測了兩件事,代表測試失敗時會有兩種可能!

3A原則 Arrange, Act, and Assert
這裡學到幾個tips
1.     面對Unit Testing的初學者,我們在導入時可以將Arrange, Act, and Assert的結構用註解隔開。
2.     Naming時也請習慣使用target, expected, and actual
3.     Assert的位置是(expected, actual) 不要搞錯位置囉!
以上作法能夠幫助Developer清楚原則與用法。

Unit Test的特性:FIRST
Fast, Independent, Repeatable, Self-Validating and Timely

(心得) Repeatable Idempotent來解釋會更有說服力
Idempotent : 無論執行幾次,結果都是相同的。

[AreEqual v.s. AreSame]
原則:(MsTest, 但我想NUnit應該也差不多)
1.     比較value type的值用AreEqual()
2.     比較reference typememory位置是否相同用AreSame()
3.     比較 Collection 可用CollectionAssert
4.     想測是否會有Exception請用[ExpectedException],切記不要自己寫try catch
Exception一定要測如果是Scenario1就預期有ExceptionCase
5.     .Net String Object的特性:String雖是Reference Type,但是有實作StringPool的緣故,所以如果是同一個值將會指到同一塊Memory,所以也擁有value type的特性。

[如何解決相依性]
接下來就進入實務上最常碰到的問題了,也開始進入導入上所面臨的困難。
Solution :

  • 單一職責
  • 依賴Interface
  • 依賴注入
  • 利用Mock Framework

1.     單一職責
Design上就盡量讓一個Class,一個Method負責單一的職責。從這裡盡量降低一些Dependency

2.     依賴Interface
我們要從使用端的角度去定義Interface,從相依的Class中抽取出能共同使用的Interface

3.     依賴注入
這邊要想個法子讓測試程式可以替換掉有相依性的production code instance
91介紹了 (1) Constructor Injection & (2) Parameter Injection
我記得之前書上還有提到(3) Factory Method 以及(4)Extract and Override
下次再補上

4.     利用Mock Framework
自己去寫上述測試程式是很累人的,也會降低Developer想寫Unit Test的意願,此時Mock Framework就能幫助大家很簡單地寫出可避開相依性的測試程式。
這次使用的NSubstitute真的很好用,也不像Rhino違反了3A原則。我們可以透過Substitute.For<T>產生stub, 再透過xxx.TestMethod1.Return(R) 取得stub預期會回傳的R (Stub 關心的是回傳值)
若是想要測Mock (與外部的互動) 也能使用xxx.Received().ExpectedMethod() 知道預期是否有呼叫ExpectedMethod() 或是 DidNotReceived()驗證不被呼叫的情況。(切記,一次只測一件事,如果要測Mock,只要驗證是否有被呼叫即可。)

91的經驗:大部分都是測Stub, Mock的比例大約10%

[PublicMethod該不該測]

不用針對它特別測!!!
但是得透過Public Method測到它

不要為了測試而測試,想想需求吧。非PublicMethod一定是在哪裡被PublicMethod使用到。
Code Coverage的建議
1.     檢視Test Case是否包含最主要的情境
2.     檢視Test Case是否包含曾經出錯的情境
3.     檢視是否有不必要的code或是缺少對應的Test Case
4.     相對比例盡量只能往上,不要往下

[Internal該如何測試]
在實務上我們有些Class是設定成Internal的,測試程式可能無法取得。
Solution :
1.     AssemblyInfo.cs 加上 [assembly:InternalsVisibleTo(“XXX.Test”)]
2.     AssemblyInfo.cs 加上 [assembly:InternalsVisibleTo(“DynamicProxyGenAssembly2”)]
要給DynamicProxyGenAssembly2看得見才能動態建立stub/mock

[其他心得]
1. TDD導入與推廣的原則
(i) 如何讓Member不要太過麻煩就能做
(ii)如何盡量不影響現有production code

2. 不要為了測試而去切Interface
要反過來問需求,我們是為了彈性才去切Interface

3. .NET Framework的Object不建議用Interface去抽換

對這堂課有興趣的朋友們
可以關注一下SkillTree什麼時候要推出第四梯的課程喔
自動測試與 TDD 實務開發(使用C#) 第三梯

系列文章
[心得文] 自動測試與TDD實務開發 Day2