國內飲料品牌曾經有句廣告詞:「Try It!」這句話 Kuma 蠻喜歡的。從小在父母呵護下長大,到了人生地不熟的地方讀書、真正遭遇挫折以後才發現,被照料得太完整反而少了自己探索的機會。這份體悟讓他往後再也不相信世上有所謂的「最佳解」——工作上的問題,受困擾的是團隊自己,當然要由團隊自己先去找答案,找到了再實際試看看,才知道好不好。

長期實踐下來,團隊或許就會發展出一套適合自己的軟體工程(Software Engineering)模式。今天要進一步聊單元測試與軟體工程之間的關係。

不要急著「導入」Extreme Programming#

Extreme Programming(XP)這本書 Kuma 蠻喜歡的。Kent Beck 在書裡提出了許多軟體工程實踐,書名「Extreme」用得相當好:當你不斷精進各種軟硬實力、把 Programming 這件事做到極致,差不多就是書中描繪的樣貌。後人把這些實踐分類,常見的圖示中:

  • 最內層是「工程實踐」:TDD、重構、簡單設計、結對程式設計。
  • 中間層是「團隊協作」。
  • 最外層是「流程改善」。

TDD 被擺在最內層,意思是你得先把工程實踐顧好,外圈的協作與流程改善才會順。如果連 Unit Test 都沒寫,卻一上來就要搞 Scrum、估算點數、做持續部署,多半不會有好結果。

有人請名師上三天課,有人合資讀完一本書,便急著「導入 XP」想一戰成名,可惜大多收場慘淡。Kent Beck 自己就提醒:不可能一口氣同時開始所有實踐,那會把團隊的精力榨乾。

正確的做法是先盤點目前最棘手的問題,再一個一個慢慢引入。所以——不要「導入」XP,而是要在合適的時機,拿來解決工作上的瓶頸。

不要急著「導入」Scrum#

Scrum 有所謂的「三本柱」:探索、調適、透明化。Kuma 提到他在呂毅老師的 LeSS 課程上聽過一個野雁南飛的故事印象深刻:北美的野雁出發前並不知道目的地,也沒有什麼「Leader」幫大家做決定,牠們只有一個共同目標——找到溫暖、有食物且安全的地方。於是先往南試一段、停下來觀察、調整方向、再試一段,重複這個開發循環(Development Loop),直到落腳。這正是 Scrum 的精神。

同樣地,很多人讀完文章標題或聽過幾次分享,就想「導入 Scrum」一口氣解決所有問題,多數也以失敗收場。

Scrum 每個 Sprint 結束時要產出 Potentially Shippable 的功能,也就是「幾乎可上線」、得通過測試。隨著產品成長,測試範圍會越來越大;如果只仰賴 QA 人工測試,不過是把工作堆給 QA,而且為了趕時程通常只能挑著測,這對「探索」「調適」沒幫助,也傷害了「透明化」。沒有自動化單元測試的 Scrum,對 QA 與老闆來說,可能還不如等做完一次性發布。

所以,不要「導入」Scrum,要在合適的時機拿它來解決瓶頸。

不要急著「導入」CI/CD 與 DevOps#

Kuma 第一份工作在某德商台灣辦公室,當時就嚴禁在產線下指令:每位工程師都要在自己電腦裝 VM,所有環境安裝、資料庫建置、程式部署、資料表調整都靠版控過的 shell script 執行,所有環境共用同一套腳本。在那個 Git 還不普及、Docker 與 k8s 都還沒紅起來的年代,這種做法已經算很成熟。

後來換到一間電商,他開始使用 Ansible,幾乎能取代過去寫 shell script 做的事,多環境、多機器的管理也方便許多。聯合部署常常 5 分鐘搞定,而隔壁團隊還在打包、寫文件、手動測試與退版修 bug。再後來認識了 Jenkins,能透過排程或 Hook 觸發自動測試、打包與部署,搭配 Ansible 簡直如虎添翼。

這些其實只是 DevOps 的一小部分,但他當時並不知道這個名詞,只是一心想優雅地解決手上的麻煩事。多年下來,團隊在 push 完之後幾乎不需要再做什麼,幾分鐘後訊息會自動發到大家手機上,把重複枯燥的事丟給機器,省下時間做機器做不到的設計與重構。

沒有足夠的單元測試,誰敢這麼放手?所以——不要「導入」CI/CD 與 DevOps,而是在合適的時機拿來解決瓶頸。

不要急著「導入」User Story#

Kuma 自承曾寫過「As a 使用者,I Want a 註冊功能,so that I can 註冊」這種為賦新詞強說愁的 User Story,直到工程師在回顧會議上抱怨看不懂,他才意識到 User Story 不是一份「文件」,而是一種「媒介」。

打個比方:在團隊裡聽到某句怪怪的暗語,外人聽不懂,但成員一聽就知道是哪個系統功能——那是因為當初圍繞那句話發生過熱烈討論,於是它成了團隊喚回那段記憶的入口。User Story 也應該如此:別再照本宣科,由 Solution 反推一個假裝的「使用者」。

例如:「現在註冊頁要填十項資料,像智障一樣,使用者非常不爽!」這種寫法是不是更有共鳴、修改方向也更明確?User Story 寫得好,場景清楚,測項自然好列,功能自然不容易做錯,並間接帶動更紮實的回歸測試(Regression Test)。

不要「導入」User Story,要在合適的時機拿來解決瓶頸。

不要再「導入」了#

寫到這裡 Kuma 心情其實有些複雜。Scrum 是個很好的東西,卻常被瞎弄而被誤會。前述的 Scrum 也可以代換成近年流行的各種 Buzz Word。

有人問過他怎麼「導入」單元測試、怎麼說服老闆給時間寫測試、怎麼讓團隊接受 Ansible、容器化等做法,他覺得這個問題很難回答,但仔細想想又很好回答:「我從來沒跟老闆多要過時間。」

單元測試、重構、自動化部署、容器化等做法,本來就是設計來幫團隊節省時間、降低錯誤率的。如果還要「多要時間」才能做這些事,不就本末倒置了嗎?

與其想著「導入」什麼酷東西,不如多觀察工作上實際的瓶頸是什麼、手上有哪些資源、學會這些工具要多久——這就是「模式」。在某個情境下,挑一個方法,解決你想解決的問題;不要拿著到處撿來的方法亂套,因為那未必適合你的問題。如同薯條炸太慢時,先回頭看看你拿來炸的是什麼鍋。

「該做什麼就去做,有問題就修正。」這是 Kuma 對軟體工程實踐一貫的態度,他也建議大家大膽地試一試。畢竟現況都這麼讓人頭痛了,再差也不會比現在差。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10274490