敏捷開發, 是一種應對快速變化需求的一種軟體開發模式. 在這個模式中, 有個自組織的跨職能團隊, 在大家一起緊密的協作下, 藉由頻繁交付小的增量, 來確認使用者或顧客的需求.
敏捷一詞來源於2001年初美國猶他州雪鳥滑雪聖地的一次聚會. 那時候有 17名軟體開發人員在度假村會面, 討論這些輕量級的開發方法, 並由 Jeff Sutherland, Ken Schwaber 和 Alistair Cockburn 發起, 一同發布了敏捷軟體開發宣言(如下表所示).
Individuals and interactions over processes and tools
個人與互動 重於 流程與工具
Working software over comprehensive documentation
可用的軟體 重於 詳盡的文件
Customer collaboration over contract negotiation
與客戶合作 重於 合約協商
Responding to change over following a plan
回應變化 重於 遵循計劃
在這個宣言中, 主要是在說明敏捷的價值觀:
人是最重要的, 他要能應付變化的思維, 而不是等待流程上教他怎麼做. 就像在測試過程中, 哪裡會出現 bug, 哪邊品質比你想像中還爛, 都是造成你計畫改不上變化, 你無法等待別人下命令.
能動才是最重要, 而不是只寫出一堆文件. 因此敏捷有很多實踐, 都是在確保隨時都能有能動可交付的產品. 例如: 測試驅動開發和持續整合等等. 早期就確認品質, 早期以較低代價來修復.
我們無法早期就知道我們想要什麼, 或者文件寫的都能了解. 因此, 需要和客戶不斷互動, 確保我們想的跟客戶想同.
一開始有計畫很重要, 但是因為外界不斷在變化, 所以更重要的是持續規劃. 尤其在測試方面, 原本的工作, 因為找到太多問題, 或者因為需求變動, 導致測試工作需要不斷調整.
你的開發方法, 能夠符合這些精神, 就可以稱為敏捷開發方法. 所以你才會聽到像是 Scrum, Extreme Programming, Kanban, Agile Unified Process … 等等, 都是敏捷開發方法. 其中以 Scrum 和 Extreme Programming 最受歡迎, 所以就稍微對他們展開一下.
Scrum是以迭代的方式,來進行產品開發和維護的一種輕量級框架。它的結構是以跨職能的團隊所組成,在固定的節奏下,交付一些產品增量給客戶,以收集客戶的回饋,然後再調整接下來要進行的方向。
整個過程是以迭代的方式進行, 每個迭代長度介於 1 到 4 週. 在迭代開始會召開 Sprint Planning, 規劃這個迭代要做哪些功能. 每天會利用 Daily Scrum, 同步和交換訊息. 在迭代結束前, 會召開 Sprint Review, 展示已完成的功能, 讓客戶可以給予回饋. 最後會用 Sprint Retrospective 討論整個流程哪些地方可以改善.
圖 12-1 Scrum 的框架
Extreme Prgoramming 認為軟體需求的不斷變化, 是軟體專案開發中不可避免的、也是應該欣然接受的現象. 因此, 希望以迭代方式, 不斷調整因應需求調整, 並且為了保持敏捷, 必須對抗軟體腐爛, 在整個開發過程中加入不少工程實踐(Engineering Practices), 來確保軟體的品質.
如圖 12-2 所示, 利用搭擋編程(Pair Programming), 兩位工程師相互交流討論, 即時給予回饋. 單元測試/測試驅動開發 搭配上持續整合, 可以不斷確認新增的代碼, 對現有系統帶來的影響.
每天也會進行每日會議同步資訊. 當功能完成時, 需要進行驗收測試. 並且迭代開始時, 需要進行迭代計畫, 規劃未來這個迭代要如何進行.
所以在下圖中你可以看到, 不同頻率有不同的反饋機制, 幫助開發團隊可以及早調整, 以交付可運行的產品.
圖 12-2 XP 中利用各種實踐來達到快速回饋
在敏捷出來後一段時間, 大約在 2009 年時, DevOps 出現了. DevOps (Development和Operations的混成詞) 是一種重視開發人員和運維人員之間溝通合作的文化、運動或慣例. 在做事的過程中, 會通過自動化軟交付和變更的流程, 來使得構建、測試、發佈軟體能夠更快捷、頻繁和可靠.
如圖 12-3所示, DevOps 分成 Plan, Code, Build, Test, Release, Deploy, Operate, Monitor 等階段. 外面那些就是各個階段可能會落實的實踐(Practices).
圖 12-3 DevOps 的流程和要處理的事情
所以根據以上面的敘述, 敏捷 和 DevOps 這樣的改變, 會對測試帶來怎樣的挑戰呢?
一般迭代的長度是 2 週, 因此開發人員光把程式寫完就不錯了, 幾乎沒有剩多少時間可以進行測試. 因此, 要如何短時間內, 把各種測試活動都做完, 這是一個巨大的挑戰.
正如前面所說, 光寫程式都來不及, 更不用說寫文件. 如果測試是測試人員來進行, 這時候他們可能需要靠通靈來想像要如何測試. 這時候要讓他們測好, 真的幾乎是不可能的任務.
每次迭代開始, 就會重新規劃, 萬一這時候有新的需求進來. 或者, 在上個迭代的檢視會議, 客戶覺得做出來跟他們想的不同, 要求要修改. 這些狀況都會需要修改, 因此測試人員需要根據這些變動, 修改他們原先的測試計畫. 有些地方甚至需要再重測. 回歸測試的次數會是瀑布式的數十倍以上.
在 Agile 或 DevOps 中常會聽到要一條龍服務, 開發人員去做測試, 導致測試人員的數目大量被減少. 當開發人員要接這麼多工作, 一方面他會忙不過來, 另一方面他往往是沒有測試相關資訊, 導致整個產品品質有下降趨勢.
除了上述原因外, 另外下面情況也讓測試這件事情, 在 Agile/DevOps 中更嚴峻:
• 單元測試沒做, 或是做得很少
• 回歸測試的工作量變大, 後來就隨意做或不做
• 開發 vs 測試 比例差很大.
• 不良的程式架構導致要做自動化測試很難
• 對測試知識不懂
• 需求變化頻繁
• 測試人員
• 能力不足
• 測試人員不會寫自動化測試
• 老闆和開發不太重視測試
• 測試人員對需求掌握度不高
• 開發和測試不太溝通和協作
根據上述的種種說明, 測試在 Agile/DevOps 進行以下調整
所謂測試左移, 就是說測試活動進行的時間, 是發生在傳統測試階段之前. 在上圖中, 我們會進行需求和設計的檢視, Pull Request, Code Review 和實例化需求(Specification by example), 這些都是在測試之前, 可以用來幫助團隊確認品質的活動.
在迭代中, 最重要的就是執行持續整合(Continuous Integration), 每當開發人員寫完一段小功能, 立刻讓持續整合機制確認是否正確, 舊的代碼是否也依然運作合宜.
除了持續整合外, 我們需要不斷確認整合起來的系統是否沒問題. 所以會跑整體的功能測試, 非功能測試(Non-functional Testing), 探索性測試(Explorating Testing). 回歸測試和驗收測試等等. 用不同角度的測試方式, 不斷驗證系統的正確性.
當要上線時, 也會做一些測試, 確保上線是沒問題的. 並且也會持續監督產品, 當有問題發生, 才能第一時間處理.
這樣的流程改變, 主要是為了對付時間短暫, 頻繁變化和測試人員不足, 我們利用多種測試來把關, 不是只靠單一種做法. 並且利用自動化方式, 讓這些事情比較可以持續進行, 這些都是開發人員擅長的.
不過, 除了自動化外, 我們也使用探索性測試, 在短時間內找到最多問題. 這部分測試人員可以幫忙.