讀書心得-JavaScript測試驅動開發

紀錄一下讀書心得,這本書因為是在說 Javascript 的 TDD,我對於這個還挺有興趣的,雖然是簡體中文書,但翻閱了一下就決定買回家閱讀了,主要是因為翻閱到異步測試這個章節,寫得還蠻不錯的,不過我應該會略過 AngularJS 的部份,畢竟沒研究過也不打算深入。

基於偷懶的大原則,以及本人技能樹的加點與後續章節不太符合,後面的幾個章節直接被我略過了
原因如下:

  1. 暫時不會接觸 node.js 更深入的東西
  2. 前端的東西未來如果會使用到測試,也應該會採用框架的方式去做,屆時再研究vue.js或是react.js等其他前端框架的測試
  3. AngularJS,因技能點、工作上都用不到,基本上不考慮使用此框架
  4. 本人打內生態系

先說感想吧:技術很多、有些你用的上,有些你用不上,絕對絕對不要學起來放著,這只是再浪費時間、精力;沒有在實務上持續運用的技術,並不能為你自己帶來價值。
或許可以借鑑,但現在資訊取得較十幾二十年前方便許多,那些時間可以讓你直接去找相關的資訊還比較有效益

軟體設計師最重要的是時間,不會在實務上用到的技術上不要花太多時間,就像是node.js那一章節,我也不用 node.js 啊,但我仍舊收穫良多,因為我看的是它解題的流程,思考的過程,而且…node.js那章節我看得懂,(笑)

我沒有太多美國時間去浪費,把時間花在家人、生活、讓自己快樂的事情上都比這些有效益。這很重要!

第 1 章 - 自動化測試讓你重獲自由

大概論述了一下測試的重要性,因為很多書都有類似的東西,闡述為甚麼要測試的緣由等等,大致翻閱了一下,這個章節學到的東西是一個專有名詞:spike 解決方案,這名詞我拿去 google 找到的都是翻譯,譯者給出的解釋是:如果在設計中碰到困難,那麼就立刻為這個部分建立一次性的可執行原型

如果與第四章搭配起來閱讀,我就把他理解為,一個能夠完成需求,但是沒有經過重構設計的原始解決方案,簡單來說就是爛 CODE,但有效

第一部分 創建自動化測試

第 2 章 - 測試驅動設計

一般的軟體安裝、套件說明後,這邊提到了金絲雀測試,大概就是確認測試框架是否可以正確運行的測試,這個步驟其實在做測試的時候一定會先做一次,但通常我是將它當成準備工作,這個可以快速驗證開發環境是否正確安裝安裝,步驟其實也很簡單,就是撰寫一個很單純的測試,內容就是直接expect(true).to.be.eql(true)這樣的東西

這個測試雖然只要確保一開始正確運作之後就沒有價值了,但保留他也有好處;如果變更了測試框架、或是在別的電腦執行,或是變更了環境變數,那麼仍舊需要重新驗證最基本的測試是否可運作,以確保測試環境是正常的。

另外也以範例、一步步地展示 TDD 的開發過程,將正向測試、反向測試、異常測試的觀念帶入;這裡也特別提醒了,我們需要關注的是行為,而不是狀態,用我的理解其實就是我們在撰寫測試的時候,不太需要去為了單純的 getter、setter 撰寫測試,我們應該將目光放在那些包含了邏輯的行為,那才是我們要測試的部分

接著讓我覺得很棒的是,書中用同一個問題,撰寫回文的 function,以 TDD 的方式在 server 端、client 端都實作一次;在 client 端透過 karma 的部份,是我很薄弱的地方,經由這個範例讓我學習了在 client 端的程式碼,透過 tdd 開發測試的方式,雖然還只是很基本的範例,還沒有牽涉到 babel,webpack 等實務應用,但是起碼知道是怎麼一回事了

第 3 章 - 異步測試

很久以前曾經上過小風的測試課程,當中有一段是 promise,記得當時就像是聽天書一樣,這個章節其實讓我很清楚地明白了為甚麼會有非同步測試這件事情,並且應該如何測試,測試過程的手法及演進,最後透過額外的第三方套件讓測試撰寫的更優雅,更語意化,這個章節給我的最大感觸是,上完課後要好好溫習,不懂得要趕緊查資料,如果是因為程度只有入門,卻上了進階班導致跟不上,那就…要有心理準備,去長見識的。學習還是先把基礎補起來吧。

不過還是沒有後悔去上課啦,因為沒有時間就是花錢買人家的經驗,吸收不了細節其實觀念還是有學到,在努力的方向上就跟別人有區別了,還是很值得。

第 4 章 - 巧妙處理依賴

我們都知道測試最困難的,是解依賴,這個章節的範例其實我覺得很經典,功能簡單,很容易理解,但是又依賴很多東西,透過這個例子可以學到怎麼把爛 Code 分離職責,逐一擊破,並為這些程式撰寫測試。
這裡有一個很棒的部分是,範例程式碼給了兩份,一份是 spike 解決方案,然後書中解析這份 spike 方案,分離職責給出一個模組化設計的圖,而在另外一個範例程式碼,將這些模組化都預先建立了一個 test 程式。這意味著,我只要能夠學習這套方法,能夠將 spike 解決方案轉化為模組化設計的圖,就可以撰寫測試了

這章節在解釋知識點的時機也很不錯,依據情境撰寫測試,發現要做的事情缺少某些知識,這時候再進行補充,這樣做少了教科書式的條列式重點,但只要是認真看過作筆記,倒是能吸收的不錯。
關於測試替身的定義我倒是第一次看到 martin fowler 的解釋版本,可能是簡體中文的關係看不是很懂他的意思,但是看範例程式碼自己理解再對照一下,還是能夠懂的,就是累了點。

這一章節含金量很高,每一段的說明、解釋、範例都很重要,值得細心研讀

第二部分 真實的自動化測試

第 5 章 - Node.js 測試驅動開發

這一個章節大概就遵循著常見的開發流程,給出了一個示範

  1. 需求說明:簡單的介紹了一下當前遇到的需求是甚麼,我們需要完成甚麼
  2. 概念設計:基於需求而提出的一個解決方案概念,將問題拆解成一個個較小的環節,並明確各自的職責
  3. 測試開發:針對各步驟進行測試驅動開發

這一章節一開始就說我們要來做一點東西,先介紹了目標,接著將程式的整體邏輯做一個概念性的設計,歸納程式流程的同時,也明確界定了職責,產生出來的圖就像是上一章節的模組化設計的圖一樣。
在這個圖裡面,可以看到問題再次被分解成一個個小步驟,並且明確的定義了各自的職責,其實也就是輸入、輸出。

到了測試驅動開發的這個階段,首先要做的是先將想到的測試記錄下來,而暫時先不要考慮是否正確,畢竟隨著時間經過,這些東西很有可能會隨著改變

隨著 TDD 的開發,第一個測試的目的是為了釐清我們會用到的介面、簽章方法,暫時不需要去實作他,後續的測試才是幫助我們實現 production code。

這章的重點應該在於如何在 TDD 的開發流程中,逐漸完善測試案例;其次,在面對較為複雜的步驟,為它單獨建立一個 spike 去實現概念,獲得較為具體的想法之後,再將 spike 拋棄,回歸到 TDD 開發流程。
簡單的說就是當你發現某個步驟太複雜,做不出來、無從下手的時候,先不要管什麼 TDD 了,直接用最髒的方式去完成它,然後,再根據你做出來的程式碼去分析、釐清裡面的邏輯、依賴關係,最後幫它加上測試案例。

再往後就是一個完整的思考、撰寫、實現 TDD 的過程範例,直到這一章節結束,在最後面有最終的設計圖,與一開始的概念設計相比較,應該會有一些感覺

第 6 章 - Express 測試驅動開發

第 7 章 - 與 DOM 和 jQuery 協作

第 8 章 - 使用 AngularJS

第 9 章 - Angular 2 測試驅動開發

第 10 章 - 集成測試和端到端測試

e2e 測試這一塊我個人偏好的是testcafe.js,對於其他工具就沒什麼了解了,雖說 e2e 測試在工作上其實也用不到,純粹是個人興趣所以研究,所以其實了解也很粗淺

現在偏好的則是cypress.iotestcafe.js已經成舊愛了

但就書中的範例來看,除了基本的測試撰寫範例,還著重的提了一下啟動服務器的部分,書裡面的範例是透過 mocha 的 hook 在測試開始前,啟動express,應該是想要更方便的測試,而不需要讓人手動的開這開那準備測試環境吧

這些方法對於.net 生態系的我完全用不上,往後應該也沒什麼機會去搞懂,基本上這個章節我只有快速翻閱過去,談不上甚麼心得

不過這邊有提到一個觀念很重要:盡量減少 e2e 測試的數量,最好是僅撰寫沒有被其他測試覆蓋到的部分。這是一個易懂難精的東西,程式還好說,花時間學應該能會;但這個就有點玄了,大概就跟怎麼寫好測試案例這個東西是一樣層級的東西,應該也是可以專門弄一本書來說的

而且 e2e 很花時間,能少最好是少一點

這邊也特別提到了page-object的概念,這概念其實在 e2e 測試一直被提到,testcafe.js 官網記得也有寫過 page-object 的範例教學,大概就是一個中間層,讓程式碼及測試程式都依賴它,這樣未來 UI 有改,ID 有改,透過 page-object 就可以很快速地調整了,不懂就看參考連結

現在寫 e2e test 的新歡是 cypress.io,不再是 testcafe.js 了

第 11 章 - 測試驅動你自己的應用

最後這章節大概就是總結這本書的一些重要概念了,其實大部分都還是在說一些老生常談的知識點,如果你也很喜歡探討觀念、這章節應該可以滿足你。

我基本上只看標題就直接略過了….簡體中文版的另外一個壞處是,標題都可以翻得很難懂