2015-06-29

社群分享 在瀑布底下玩Scrum


今天很高興被AgileCommunity.tw邀請來跟各位分享一下我們Team的Practice

身在一個大型軟體公司稍微傳統的部門下也是能夠玩SCRUM的
這場sharing將會和大家分享我們在瀑布底下碰到問題之後
如何採用一些SCRUM的Practice以及Tool的協助來幫助我們解決問題

內容包括:
Team Member的緊密配合
如何以JIRA視覺化我們的工作狀態
如何改善Standup Meeting的效率
如何在每次的Sprint結束後都能更進步 - Retrospective Meeting

我的場次被安排在第二場

所以先來聽聽第一場的David怎麼介紹SCRUM

我擷取幾張有趣的部分


敏捷大師們
沒有他們就沒有今天的敏捷
要感謝它們的努力阿~


最強的人不見得是能生存下來的人
但能生存下來的人 一定是最能適應改變的~
我們要有能夠因應改變的能力
所以不要再一直說需求,環境一直變了 因為這些一直在變
我們該改變自己 讓自己能夠適應變化



瀑布式的缺點就是需求到最後才會發現不是User要的
SCRUM的優點就是每個Sprint都能再Review一次需求到底是不是User要的


但是SCRUM的缺點就是沒有工程實踐
才會讓人覺得很難run 沒有效
我覺得真的很有道理 但是SCRUM提供了一個很好的Process
接下來就是團隊的努力了 如果團隊覺得真的需要幾個Practice把事情做好
那我們就把Practice補上吧



成功者會養成開始的習慣
所以聽到什麼 看到什麼 就開始做吧
從自己開始做起


SCRUM真的只是個Framework而已
他建議我們該做什麼 但沒有說要怎麼做
我認為我們應該要先採用Retrospective蒐集一下團隊的想法
當團隊覺得哪邊有問題的時候 SCRUM是否能解決問題?
然後自己想出Practice

了解它 調整它

第二場 - 在瀑布底下玩Scrum

這場我跟大家分享我們Team的Practice

[Team Member的緊密配合]
Group Design
SCRUM的Team很講求跨功能 在我們公司因為分工明確很難達成這一點
但我們透過Group Design 把大家集合在一起討論 設計 思考
透過群體智慧的力量 把Spec確認清楚
基本上我認為這還蠻符合SCRUM大家一起努力打拼的精神

[如何以JIRA視覺化我們的工作狀態]
原本JIRA是一套Bug的tracking system 但我們發現他還有agile board可以用
所以我們就拿來管理開發的工作項目
將我們傳統每個人要填寫的WBS 轉而填到JIRA的ISSUE上
Board仍是沿用我們以前傳統白板的Column
但是我這次新增一個Column - Pending
無論什麼原因 只要你的task是被卡住的 你就放到Pending這個Column
用意是 希望被卡住的東西提早被團隊看到
這樣才能幫忙處理

執行上則是讓Member從過去的便裡貼轉變成JIRA的ISSUE
導入之後的效果蠻不錯的 專案進度公開透明
大家都清楚每個人的進度
甚至還有member反應說 現在他可以知道哪邊稍微落後 他可以主動幫忙

以前的白板便利貼

現在轉變成JIRA上的Board



[如何改善Daily Scrum的效率]
我們團隊是個30人的大團隊
原本的Daily Scrum希望大家怎麼報告呢?

  • 昨天做了什麼?
  • 今天預計要做什麼?
  • 有沒有阻礙?

但是這類型的報告在30人團隊上實行會是個惡夢

SCRUM:用一半的時間做兩倍的事的作者Jeff Sutherland也強調
他覺得理想的方式應該是

團員們圍在一起討論戰術的景象 !!!




所以我們導入JIRA之後 在Daily Scrum的方式就變成了重點報告
我們變成針對Task討論 而不是每個人的進度報告

我們的遊戲規則是這樣
訂一個更新時間 e.g. 中午12:00
我就以這個時間當作分界點 去JIRA上抓每個Column的數據
然後在Daily Scrum前寄出通知信 通知member今天的情況
以及等下那些task要報告

這邊也加入視覺化的效果
列紅字的代表這個task有delay
列黑字的雖然沒有delay
但是他被放到Pending或是新增加到To Do的
也會拿出來討論

我們的白板從滿滿的便利貼,轉而填上目前專案的總體進度資訊;Daily Scrum也更著重於概述需要幫忙的項目並尋求協助。

如此這麼實行下來 Daily Scrum變得更有效率
專案資訊也更透明化
當然Member也能再透過JIRA看到更detail的資訊

[如何在每次的Sprint結束後都能更進步 - Retrospective Meeting]
如果你們還沒導入SCRUM
那我推薦第一個要實行的項目就是Retrospective Meeting了

透過Retrospective Meeting先蒐集大家的想法
我覺得一個重點在於
要大家真的覺得痛 覺得有問題了
我們再來討論要導入什麼Solution來解決

先有問題 再有Solution會比起你硬推Process來的有效喔

最後我跟大家分享幾點心得



從現在開始從自己開始做起吧

樂於分享才會教學相長
一切都以“win-win”的角度切入 要讓member覺得這是對他有幫助的
他才會接受

最後是真的有問題才是有問題 不要硬推 導入注定失敗
如果大家都覺得沒問題 只有你覺得有問題 是誰的問題?


最後送給大家一句話



其實還有更好的作法 只是你還不知道而已

2015-06-23

[讀書筆記] Deploying and Releasing Applications

Deploying and Releasing Applications

1.         Creating a Release Strategy
          i.              The Release Plan
(1) 首次部署的步驟
(2) 預計怎麼進行Smoke Test
(3) 如果部署失敗,如何取消
(4) 如何備份與還原
(5) Log
(6) 如何監控
(7) 資料如何轉移
(8) 前一次部署失敗的紀錄及後續Solution

         ii.              Releasing Products

2.         Deploying and Promoting Your Application

          i.              The First Deployment
首次部署會發生在首次Iteration結束時,你應具備以下內容:
                (1) Deployment pipeline’s commit stage
        (2) A production-like environment
        (3) An automated process
        (4) A simple smoke test

A production-like environment
(1) The same OS
(2) The same software (none of the development toolchain)
        (3) Be managed the same way as the production environment (Chapter11)
        (4) The UAT environment should be representative of your clients’ hardware statistics

         ii.              Modeling Your Release Process and Promoting Builds
                

建置必須得通過那些階段?
每個階段的驗收標準?
每個驗收標準由誰批准?

再次強調 自動化部屬機制 使Upgrade變得容易

       iii.              Promoting Configuration
需要upgrade的不只是Binary Files
還包括了環境及應用程式的設置
利用smoke test 驗證設置資訊是否正確

       iv.              Orchestration
Orchestration => 管絃樂的編制。
因為應用程式可能會共用同一個環境,所以要確保不會影響其他程式

         v.              Deployments to Staging Environments
在你將程式交出去之前,應該要在試運行環境執行最後的測試。
在專案開始前就必須規劃以下事項:
(1) 確保所有環境OK
(2) 自動化流程
(3) Smoke Test
(4) 測量應用程式的warm-up
(5) 與外部系統進行整合測試
(6) Blue-Green Deployment
(7) Canary Release
(8) 將通過測試的變更版本部署至試運行環境

3.         Rolling Back Deployments and Zero-Downtime Releases
還原時注意兩個原則:
(1) 備份
(2) 練習還原計劃

          i.              Rolling Back by Redeploying the Previous Good Version
最簡單
重新部署前一個沒有問題的版本

缺點:
難以除錯
新資料可能遺失

         ii.              Zero-Downtime Releases
User從一個版本幾乎瞬間轉移到另一個版本,後面會介紹兩種強大的方法。Blue-Green Deployments AND Canary Releasing

       iii.              Blue-Green Deployments
                

兩個相同的生產環境:藍環境綠環境
假如User目前在綠環境,如果要發佈新版本,會先發佈至藍環境,等一切就緒之後,再將User切到藍環境
問題:
小心管理DB
Solution
暫時唯獨
Chapter12

如果只有一個生產環境,也可以使用Blue-Green Deployment
ð 讓應用程式的副本存取自己的資源

變體:shadow environment releasing (影子環境發佈)
試運行環境與生產環境彼此切換

       iv.              Canary Releasing
                 

金絲雀發佈就是把應用程式的某個新版本部署到生產環境的部分伺服器中。進而快速取得回饋。
好處:
(1) 容易還原
   => User 引導回沒問題的版本
(2) 能做A/B Testing
   => 小樣本測試新功能
(3) 方便做容量測試
   => 透過逐漸增加負載的方式做容量測試

問題:
如果是需要User自行安裝在自己環境的軟體不適用

Solution
讓軟體能夠自動地從伺服器中取得新版本並自動升級

限制:
共用資源,所以要考慮
    (1) 資源於不同版本間的相容性
    (2) 非共用架構

生產環境中盡量保留兩個版本以內

4.         Emergency Fixes
任何情況下,緊急修復都不能破壞流程。緊急修復版本也要使用相同的建置、部署、測試與發佈流程。

有時候還原比部署新的修復更划算

5.         Continuous Deployment
再次強調 自動化 (包含部署到生產環境)

Continuous Deployment能與Canary Releasing結合使用,透過自動化流程將新版本發佈給一小群User,一旦確認新版本沒有問題,才發佈給全部的User。如此能降低持續部署的風險。

如果是User需要自行安裝的軟體,需要考慮下面4點:
        (1) Managing the upgrade experience
        (2) Migrating binaries, data, and configuration
        (3) Testing the upgrade process
(4) Getting crash reports from users

如果Upgrade很不穩定,那User選擇不要Upgrade很正確。
如果Upgrade很穩定,那沒必要給User選擇。

作者認為正確的作法是:
Upgrade失敗時,程式必須能自動地還原至上一版並將失敗報告提供給Team。當Team修復這個問題,再次發動部署。這些應該悄悄發生,User不需要知道。

6.         Tips and Tricks
          i.              The People Who Do the Deployment Should Be Involved in Creating the Deployment Process
再次強調,真正要執行部署的人從流程開始時就應該開始參與。

         ii.              Log Deployment Activities

       iii.              Don’t Delete the Old Files, Move Them
不要刪除舊的檔案,要移動到別的位置
不要讓舊的檔案留在原處

       iv.              Deployment Is the Whole Team’s Responsibility
不要有所謂的部署專家,整個Team都該參與部署

         v.              Server Applications Should Not Have GUIs
自動化,不要有GUI

       vi.              Have a Warm-Up Period for a New Deployment
要有足夠的時間預熱

      vii.              Fail Fast
部署Script應該納入測試當中
不需要全面性的Unit Test,只需Smoke Test

    viii.              Don’t Make Changes Directly on the Production Environment
切記,不要直接修改生產環境,完全按照流程走

7.         Summary
  • 一切要自動化
  • 越頻繁地發佈,風險越小
  • Blue-Green Deployments 以及Canary Releasing
  • Team Member一起參與





2015-06-19

[Product Feature Enhancement Competition] 各位夥伴 我們奪下第一囉


公司在6/30將要舉行Engineer Day的活動 其中一項比賽 Product Feature Enhancement Competition則是提前在6/16舉行
我們是在前一個星期蒐集大家的Idea
一起Brain Storming Feature Enhancement的可行性
這邊要感謝HIE他們一口氣就貢獻了絕大部分的想法
才能讓我們有個討論的基底

[積極爭取]
在會議中要決定上台演講的人
講完一片沉默..............
於是我就又在腦中跑過了20秒鐘的勇氣
自願接下這個工作
這邊要感謝大家的承讓

其實這機會真的很難得
勇敢爭取 機會就是你的

[少即是多]
演講的時間是6分鐘 準備時間不到1個星期
確定接下演講的工作之後
我就以我自己的想法從10幾個idea裡面挑出4個當作草稿
當晚只是光把這4個想法描述一次就花了8分鐘
所以隔天的草稿練習就刪了其中一項idea

兩天後第一次彩排
這邊要感謝小白跟小亨利一直幫我找人來聽我的練習
這次彩排找了第一次來聽我們idea的同事
果然發現了一些盲點
我們雖然剩下3個idea
可是在6分鐘內仍是很難講清楚
導致講完了 觀眾也不清楚我們的主軸

所以根據討論結果 我們又刪掉一個idea
並且將焦點鎖定在
 1. 要描述問題
 2. 提供Solution
 3. 最後總結價值

比賽前一天 第二次彩排
到了第二次彩排 其實我講的內容大致上已經確定
也設計好要用一個故事貫穿全場
從故事中帶出問題,以及我們的Solution
這次彩排其實已經蠻完整的 但還少了點什麼
第一次聽的觀眾 在Q&A的時候也有搞混我們的訴求

就是少了圖 果然光用文字敘述還是不能深入印象

於是我們就分工合作 感謝Eason跟小白幫我生一些圖
其實這很困難的 因為我們在講的是一個Trend Micro尚未做出的產品
沒有對應的UI 其實是很難截圖的
最後我就把一些文字描述改成這些圖跟動畫

用兩個idea 幾張大圖 來表示我們的想法
結果論來說 少即是多的戰略是成功的

[從TED的啟示]

最近剛好才讀了一本書 : 破解!撼動全世界的TED秘技
於是我就想應用在這次的演講中
1. 練習練習再練習
2. 不要脫稿演出

於是我在賽前就練習了約40次 到最後果然那一張投影片到那一張 每張要講什麼都記得清清楚楚
因為時間只有6分鐘 所以我這次要求自己不要脫稿演出
以往我常常會脫稿 因為都不寫稿子 每次都照大綱發揮
這次是逼自己不能脫稿 就結果來看 果然是很順的把事前準備的東西講完

[比賽當天]
當天901滿滿的觀眾 加上評審都是公司的大頭們
其實越接近上台的時候 就越緊張

我是最後一組上台的 在台下其實就沒在準備了
一方面這樣也不緊張 一方面別組的演講也很精采
尤其我上一組的演講
講的真的很好 有深度有廣度
說什麼有塊很有門檻的藍海市場
是我們Trend Micro很有機會切入的一塊
超級打動人的

最後輪到我了 一開始真的還挺緊張的
因為第一次在大頭面前報告 面對滿場的觀眾(大都是很資深的)
但我準備的第一個笑點讓大家笑了之後
之後就講開了 一路順暢

結束之後的Q&A很熱絡
大頭們也還蠻欣賞我們其中一個Idea (幸好壓對了寶阿)

兩天後公布結果
結果我們跟上一組並列第一
恭喜大家 我們的辛苦沒有白費
接下來要在Engineer Day中跟台下1000名同事sharing我們的想法囉
看來賈格的故事要繼續走下去了XD

[心得感想]
這次的演講很有Startup公司在創投面前 爭取認同的感覺
我們提出了一個全新的Idea 希望公司會買單
在眾多Idea裡面要脫穎而出

少即是多

果然能把主軸描述清楚

各位 我們真的做到了
謝謝你們 謝謝各位的幫忙
這真的是一次很棒的成長~

2015-06-10

[CI] [Jenkins] Jenkins 初體驗

Jenkins初體驗

本周要demo用Jenkins建置第一個Build
試了一整天終於把內褲版成功了
筆記一下

Step1 安裝Jenkins
Windows上安裝蠻簡單的,直接install即可

Step2 安裝對應的Plugin
我目前裝了 P4 Plugin以及MSBuild Plugin


Step3 建置第一個Build
先用Local Build
P4的連結等下一次

Step4 Command
因為用MSBuild Build Fail
所以我只好先用script裡面寫的devenv


因為環境變數設了都抓不到 所以先用絕對路徑

[補充 : MSBuild的設定]
當裝完MSBuild Plugin時 要去Configure System設定MSBuild


設完之後就能在Job的設定中找到



Step5 Build Now
可以開Console Output看過程
最後可以到首頁看結果


追蹤Issue
Q1 : 相對變數怎麼使用
Q2 : 如何跟P4連結
Q3 : 設定通知
Q4 : 查查MSBuild為何會Build Fail?


2015-06-07

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

Day2 的教學順序是先教我們怎麼使用SeleniumWeb-Testing;中間則是介紹了FluentAutomation以及Page Objects;最後則是帶到了Refactoring

而我的觀戰重點則是在於Refactoring。還記得以前我的Refactoring都是耗時費力,由上往下的設計模式。Refactor完也不敢保證有沒有side effectDay2則是學到了如何有效攻克Refactoring。確實相當實用阿~

Joey提供的Lab很寫實地反映了一個可以執行卻是寫得很爛的設計。你不能說他錯,前輩們的智慧讓這段code是可以執行的。但是它的確設計的很爛,邏輯全都包在一個btnXXX_Click Method中,很眼熟吧?是不是很多人都這樣設計呢?

還是要說,Joey這份Lab : lab6-RefactoringWebStie,著實設計的不錯,讓我們一步一步地Refactoring。這份Lab的題目是根據貨品的重量、長、寬、高以及不同的物流商,我們提供不同的運費。接下來就看看一步步該注意的原則吧。

1. 首先,必須要建立測試。

通常我們若沒有寫Unit Test的習慣,Refactoring就像之前我的耗力費時的作品一樣,是沒有效率的。我常常聽到別人不寫測試或是不敢Refactoring的理由是:
    (1) ~ 以前就沒寫UT了阿~ 現在想要也來不及加了~
    (2) ~ UT很好,但適合New Project,我們不適合。
    (3) ~ 我們都是Legacy code,沒辦法測的啦~
    (4) 這影響範圍太大,我怕有Side Effect。先不要動好了。

很高興在這堂課我看見了曙光。沒有Unit Test沒關係,我就建立一個外圍最大包的測試。這樣總行了吧?藉由一個外圍最大包的整合測試來保護,我們就能夠安心地Refactoring了,一旦Refactor失敗,測試就告訴你Fail。經由這快速的回饋,我們就能夠一步步把Refactoring做好。
於是乎,Joey就帶到了Web-Testing。如果我們的ProjectWeb類型的,就可以利用Selenium這套Tool來錄下WebUITesting Script並驗證一些行為。而Selenium更強大的是,它能夠將Testing Script轉變成NUnitTesting Code,並由Test Project去驅動這個測試。這樣就能在Test Case中自動化地驗證Web的行為。

如此,你最外頭已經有測試保護了,接下來就能放心地做Refactoring

補充:或許QA會覺得Selenium轉化成的Testing Code不夠直覺,所以可以參考能提高Testing Code可讀性與維護性的FluentAutomationPage Objects Pattern (Selenium官方推薦的方式)

2. 讓程式邏輯與網頁UI分離。
很多人習慣讓WebForm控制項的邏輯寫在cs中。
For example

這些code都跟UI耦合,從控制項中取得值,並運算一些邏輯之後再填回去控制項。

其實我們可以考慮從這裡將WebForm控制項抽離,用一個自行定義Object (方便抽換),來取代,這樣可以降低耦合
For example :


3. 重構-擷取方法 : 先將一大串code 擷取成Method

下一步則是將混在一起的邏輯運算擷取出來變成一個Method

4. 重構-職責分離(主動詞分離),將商業邏輯從網站抽到 library


原本計算運費的商業邏輯跟網頁混在一起,很難去各別測計算運費的,所以我們可以將商業邏輯抽到Library去,這樣就能測它了。這邊要注意的是,主動詞分離的原則。
For exampleUser選擇黑貓這個物流商,那麼根據商品屬性以及黑貓的運算邏輯,我們可以設計出Blackcat這個Class以及它有一個計算運費的MethodCalculateFee。而這個Method的內容就可以塞入Step3剛剛擷取的Method

到了這一步之後,我們就能確保網頁應該不包含任何計算運費的邏輯,因為我們已經將計算運費的職責委託給Blackcat這個Class來處理

5. Unit Test - Library建立Unit Test

Step4將邏輯切到Library之後,我們就能對它做Unit Test。看吧!到了這一步,是不是就能做測試了呢?

6. 持續Refactoring
有了最外圍的整合測試加上Library的單元測試,我們就能放心地持續一直Refactor下去,無論你是想要擷取成介面或是考慮將生成物件的職責獨立出來都能放心地做了。只要測試有通過就好。

以上幾點原則,就是攻克一大坨code的方法。
補充一個我很欣賞Joey的一個手法:Focus on the current content

TipsFocus on the current content
由小處著手,從這段code出發,不會跳來跳去。這實作其實蠻難描述的,但就是藉著IDE的協助,當需要某個PropertyMethod或是Class時先用手刻一個Name,再透過IDE自動產生對應的code。讓programmer不須跳來跳去地自己產生。如此專注的結果也反映了寫code的效率

Extract and Override
解legacy code的暫時解,非正統解
將切不掉的東西,放到private method,並更改為protected virtual
Test Code再繼承這個Class之後覆寫掉
我們可以先用這個解法先建立起測試,之後再用正統的方法Refactoring這段。

最後想說的是
原則是這樣沒錯,但還是需要練習練習再練習
練習是不會騙人的。
也不要再說範圍太大不可以測了,如何一步步把範圍縮小到可以測就是我們接下來的事了。

補充: Selenium其實是一種化學元素 - 硒
補充: 可用CodeMaid來分析Method的複雜度

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