Node.js 單元測試:workflow

發表於2015-12-29

Node.js 單元測試:workflow

Talk is cheap, show me the code!

是否還記得小明在《 Node.js 單元測試之我要寫測試》裡引用的這句話麼,不過引用了之後,小明就像跑路了一般再也沒見其 code……其實呀,不知道大家有沒有關注最近比較火 minggeJs, 稍微聯想下你就知道小明最近在忙啥了 O(∩_∩)O~~

雖說小明現在還寫不出 minggeJs 這樣的前端庫,不過,小明想說的是:當你準備開源一個庫的時候,一定要寫單元測試;當你要使用一個開源庫的時候,單元測試的覆蓋率是衡量質量的最重要標準之一

好了,扯了這麼多閒話之後,明哥(不對,是小明……)接下來介紹一下在專案裡單元測試整個流程是如何的。

Node.js 專屬之 npm scripts

起初,小明將 Mocha 和 istanbul 裝在全域性命令下,然後每個專案都使用全域性的命令,後來發現多人合作時會因為版本不一致而報錯,因此果斷將 Mocha 之類的裝在專案的 node_modules/ 下:

然後只需要執行下面兩條命令即可:

然而每次都執行這麼長的命令讓隔壁(座位)的老王實在看不下去了,於是就告訴小明 npm scripts 的用法。只需要在 package.json 裡定義幾個命令即可:

如此之後,每次寫完程式碼,小明只需要執行 npm run test/cov 即可,省事了很多。

不知道諸位有沒有注意到,小明在 'test/*.test.js' 上故意加了一個引號,這一點也是小明被坑了之後才發現的:執行 shell 命令時,如果引數中包含如 test/*.test.js 這種 glob 模式,對應的 shell 會自動解析掉,但是不同的 shell 對 glob 的實現又不一致,因此就會出現匹配檔案出錯的問題,當加了引號之後,shell 會把引數原封不動的交給 Mocha(或者其他工具)來解析,這樣才能保持不同 shell 的一致性。

當然,npm scripts 還有很多對於 Node.js 開發者很便利的功能,請參閱文末的相關連結。

構建利器 makefile

隨著程式碼的積累,小明寫的單測也越來越多,有時候可能只需要執行某一個測試檔案,所以小明希望能通過命令列引數將需要測試的單個檔案傳進去,這時候 npm scripts 就顯得捉襟見肘了。於是小明繼續秉持著「有問題找老王」的原則,老王毫不猶豫的給小明推薦了 makefile.

關於 makefile 的介紹,網上有很多的資料,小明的簡單理解就是:makefile 就是將某個流程(如編譯、打包、構建等)包含的所有相關命令整合到一個 make 命令下,極大的方便開發者。具體到目前的場景,可以參照如下的示例:

在專案裡定義瞭如上的 makefile 檔案後,只需要執行 make test 就可以跑單元測試了,並且上面提到的傳引數的問題也可以迎刃而解:make test test=test/util.test.js. 相對於 npm scripts, makefile 藉助 shell 指令碼的能力要強大靈活很多,然而一個不太好的訊息是:windows 並不支援 makefile……

持續整合

在經過了上面的這些步驟之後,小明在本地已經可以完美的執行單元測試了,然而在跟小夥伴們合作的過程中,小明發現有的同學並不是很關注這個事情,單元測試沒跑通過就將程式碼 push 到了遠端倉庫,這時候就需要其他同學來幫忙擦屁股,很是不方便。

於是,老王就告訴了小明持續整合這個東西,所謂持續整合,簡單來講就是:在程式碼 push 之後,對程式碼進行一系列的構建,比如 lint 檢測、單元測試、部署等,藉此提高程式碼的質量以及多人合作開發效率。而在 Node.js 領域,這方面比較優秀的工具就是 travis-ci 了,小明也順便體驗了一下 travis-ci, 按照其三步走的接入流程的確是非常之方便。

然而,小明平時開發的倉庫大部分都是託管在內部的,沒法使用面向 GitHub 的 travis-ci, 這一次小明決定不再去問老王了,程式設計師嘛,造輪子的功能還是要有的。於是,在一個多月的開發後,小明基於內部的其他服務做出了一個八九不離十的持續整合系統,名曰 UITest-ci:

這個系統可以執行單測、執行 lint、可以生成覆蓋率報表、可以通知開發者整合結果、同時提供徽章服務,近乎完美。之後有時間了再詳細介紹這個系統的設計和實現吧 :)

總結

至此,小明介紹了單元測試各個部分的相關概念以及整個工作流程是如何的,接下來,我們會面對專案中更具體的一些單測問題,比如:如何用 supertest 做介面測試、如何測試私有方法、如何針對命令列工具做單測等等。敬請期待~