圖片截自聯合新聞網
筆者最近在看一個邀請影視明星來進行專業運動的節目:「全明星運動會」。節目是蠻有趣的,這卻讓筆者不禁思考,為什麼真正專業的運動員,甚至是國手,上場比賽時我們性質缺缺,但這些不專業,甚至是連入門程度都不到的明星們進行的運動競賽,我們卻看得這麼津津有味?我是不知道啦,反正想不通也就算了,看起來這個節目應該也就這兩季了…
在上一篇中,我們討論了 TDD 的基本操作手法與運行原理,花了一些篇幅來解釋它能解決什麼問題,以及為什麼。至此,讀者也許不免懷疑:「既然 TDD 這麼棒,那為什麼不是每個人都要用?為什麼我用起來反而很不順?」
沒錯,TDD 本來就不是一個完美的 Solution,要想享受它的好處,是得付出一點代價的。
今天我們來聊聊看,究竟 TDD 這套方法,與 Kent Beck 的 TDD 這本書,到底發生什麼事。
本文主要整理自 Teddy Chen 的 「搞笑談軟工」、 91 的培訓課程內容,與拙作「Kuma 老師的軟體工程教室」中的一些論述,並加入筆者現在的想法,詳情請參閱 Reference。
筆者認為,TDD 要入門是不難的,只要嚴守 TDD 規定的流程來走,不要急著一次跨太大步,理應不會出什麼亂子。然而,TDD 難也正是難在不容易「嚴守流程」。為什麼?因為「要求的自主管理太嚴格」。
怎麼說呢?讀者如果自己有實際操作過一陣子 TDD,並搭配 Kent Beck 的 TDD 一書來學習,應該不難發現,要做到 Kent Beck 那樣出神入化其實沒那麼容易,好像還差了點什麼。筆者畢竟也只是一個普通的 RD,所以也有這種感覺。經過一番研究,筆者認為要想活用 TDD,以下能力是需要的:
TDD 提倡的是「避免浪費」,我們做了很多事都在避免程式碼的浪費,因為多打字就是多浪費時間,但回到源頭,如果我們對使用者的現況、困難,與期待都搞不清楚,只會整天要求使用者「確認需求」、「訂好規格」,就算我們做得再快再好,也解決不了使用者的問題,最後還是得重做。因此,「避免浪費」,要從好的需求訪談開始。
了解了使用者的問題後,下一步就是「解釋給 RD 聽」。什麼,你說你自己訪談自己開發?那的確是會好一點,但也還是省不了在腦中(或在紙上)建立一個「模型」,來描述使用者現在的 context 與期待未來的新 context 的步驟。這是開發時重要的依據,必須時時參考著做,不然晚點隨著開發的進行,RD 很容易掉入細節,而忘記自己走到哪去,因此走了歪路,再次造成浪費。如果做到一半發現模型有變,那就改沒關係,但不能沒有。
大家在看 Kent Beck 的書時,肯定覺得作者超級強的,沒有畫圖、沒有草稿,就這樣一步一步,慢慢把東西給做出來,但自己做時卻發現完全不是那麼一回事。為什麼(除了因為對方是大師以外)?因為 Kent 在書中雖然沒寫,但筆者認為他不可能對這東西的成品樣貌完全沒有一點點預期。這個預期可能很模糊,也可能與最終成品的樣貌很不一樣,甚至可能在開發過程中不斷改變,但他一定有個預期,否則程式碼很難發展下去。因此,再模糊、再抽象也好,建立一個模型是必須的,筆著認為這項能力應該要有,否則 TDD 不容易做得好。
有了模型以後,我們就要來進行分析,並提出 Solution,並決定好這個 Solution 必須要「在什麼條件下,有什麼表現」。這對後續寫測試來說很重要,對 TDD 來說更重要,因為 TDD 就是「測試」在驅動開發的嘛,測試好寫當然重要!一樣,這些測項如果列得好又準又小,又能彼此獨立,TDD 執行起來就能如虎添翼。反之,You know the rest...
有了測項,我們要先來做一件事:決定「誰是第一個」。列得好的測項,每個測項都代表一個特性。雖說最終都得全部完成,但其實測項完成的先後順序定得好,可以讓每一步都走得小小的,能夠更符合 TDD 的原則。因此,安排先後次序的能力,也是 TDD 要做得好,很重要的一環。
商業邏輯是抽象的,coding是細節的。RD 的工作就是整天在抽象與細節之間跳來跳來跳去。跳久了,總不免不小心偏離了抽象而不自覺,這是程式的方向就可以不小心偏了。抽象思考的能力,指的是隨時搞得清楚這行 code 是為了什麼而打的,亦即,「15 秒前你決定要實現的邏輯,跟你現在正在打的這行 code,是不是同一件事」。一旦偏離,浪費就出現了。因此,為了讓我們隨時保持正確的 coding 方向,「維持抽象思考」是不可或缺的能力。
在有了 Solution,也決定要先做什麼以後,就是實際把 code 與測式寫出來了。這是一個「硬碰硬」的事情,沒有繞開的可能性。舉個例子,當你決定在這裡「問 DataBase 有沒有符合條件的學生,有就發通知,沒有就回傳 400 給前端」,或是你想要「找出這個學生的清單中,微積分最高分的前三名,如果有重考的就採較高分計算」,從你雙手碰到鍵盤起算,到最終打出來了一份 code,中間要停下來查幾次 StackOverflow?不論前面的準備做得再好,「寫 code」還是一件避不了的事,因此,有好的「碼農」能力還是很重要的,它一定不能成為你開發中的瓶頸。
順道一提,「你知道 AI 現在已經能寫 code 了嗎?」這不是危言聳聽,這是正在發生的事情。
TDD 要求我們「先讓它 compile 能過,再讓它對,再讓它變好。」前兩項我們可以靠 IDE 與 Unit Test 幫忙,但第三項,至少目前為止你得靠自己。你有過以下經驗嗎?主管指著一段 code 問你:「這裡有什麼 code smell?」你呆住了,你覺得這段寫得棒極了,自你生眼晴發目眉以來,你都是這麼寫的,從不覺得有什麼問題。如果上述情況你經常遇到,那恭喜你,有了一個很明確的改善目標:「加強辨識壞味道能力」。
而且要趕快改善,否則你會幾乎完全無法進行下一個步驟:重構。
能指認出 code smell,下一個挑戰就是重構了。你知道這裡有 Data Clump 的壞味道,你知道這裡違反了迪米特法則,問題是要怎麼重構?沒有好的重構知識與能力,在 TDD 的過程中,就算感覺這裡怪怪的,也無法很快地重構成更好的樣子。因此,好的 TDD 也會需要開發者具有好的重構能力。
最後,這是筆者接觸過的 RD 們,最常忽略的能力了。你知道這裡要把方法抽成 Delegate,你知道這裡要抽一個 interface 出去,並讓呼叫端全部改使用 Interface。你都知道,但你要花多久才能把這件事實現?五分鐘是肯定不能接受的。在 TDD 的流程中,開發者的腦筋是轉得很快的。而大腦的思考最怕被中斷。如果打斷你思考的是你老闆的電話,那沒辦法;如果是你自己慢得要死的手指,那就很嘔了。
三秒會太短嗎?十秒?三十秒夠了吧?不能再長了。再長,你的思緒都會被你自己的手速中斷,思緒一旦中斷,要再加速就費勁兒了。是故,練習吧!
圖片截自「喜劇之王」
我們花了不算短的篇幅,來描述要操作好的 TDD ,你應該具備什麼能力。事實上,這些能力不是專屬 TDD 的。筆者認為,所有「優秀的 RD」都應該具備以上的能力。而一旦你具備了這些能力,不要說 TDD 了,ADD、BDD、CDD、… 應該是什麼 DD 都難不倒你,到了那時,是不是 TDD 好像也不是那麼重要了。所以身為 RD,做好該做的,練好該練的,流程什麼的自然學得快、用得好。
圖片截自「三個傻瓜」
謎之聲:「All is well!」
ithelp2021
在看Kent Beck的書時,我就好奇他的to-do list是從哪裡來的?其中的測試項又是從何而來?
以終為始,我知道是從需求而來,可是如何從需求中提取測試項?始終不得其法!
本文為我指明了方向,請作者指點一下如何有意識地培養以下能力:
該看哪些資料?做哪些練習?
謝謝
那天工作坊結束在每人說一句話的時候,就覺得 TDD 需要不少能力,但當然見識不足只說出一點點。
這樣列出來看了真開心XDD 我會繼續努力的!!!