Facebook推出JavaScript單元測試和自動化Mock工具Jest

發表於2014-06-07

Facebook 釋出了 Jest,一個開源的、基於 Jasmine 框架的 JavaScript 單元測試工具。

Jest 源於 Facebook 兩年前的構想,用於快速、可靠地測試 Web 聊天應用。它吸引了公司內部的興趣,Facebook 的一名軟體工程師 Jeff Morrison 半年前又重拾這個專案,改善它的效能,並將其開源。

在最基礎層面,Jest 被設計用於快速、簡單地編寫地道的 JavaScript 測試。Jest 自動模擬 require ()返回的 CommonJS 模組,並提供了包括內建的測試環境 Dom API 支援、合理的預設值、預處理程式碼和預設執行並行測試在內的特性。通過在並行程式中同時執行測試,Jest 讓測試更快地結束。

  Morrison 說:

Jest 的目標是減少開始測試一個專案所要花費的時間和認知負荷,因此它提供了大部分你需要的現成工具:快速的命令列介面、Mock 工具集以及它的自動模組 Mock 系統。

此外,如果你在尋找隔離工具例如 Mock 庫,大部分其它工具將讓你在測試中(甚至經常在你的主程式碼中)寫一些不盡如人意的樣板程式碼,以使其生效。

我們已經在 Facebook 親眼看到花更多的時間用於開發你的應用是多麼重要(相對於花時間去準備開發你的應用),而這就是 Jest 關注並正在解決的問題。

Jest 與 Jasmine 框架的區別是在後者之上增加了一些層。最值得注意的是,執行測試時,Jest 會自動模擬依賴。Jest 自動為每個依賴的模組生成 Mock,並預設提供這些 Mock,這樣就可以很容易地隔離模組的依賴。Morrison 說對於新測試,預設會進行隔離,開發人員現在也能夠“完全控制”需要隔離多少模組。每個測試都可以指明哪些模組應該或者不應該 Mock。

關於自動化 Mock,Facebook 的文件有進一步的說明

實際上,Jest 在測試環境中執行自己的 require ()函式。Jest 的自定義 require ()函式載入真正的模組,檢查它是什麼樣子,然後基於它所看到的建立一個 Mock 版本並返回。也就是說,Jest 將給你一個與真實模組具有相同形狀的物件,但它模擬每一個 Export 值而不是實際的值。

儘管 Jest 引入了自動化 Mock,需要注意的是,開發者仍然可以使用 jest.mock ()和 jest.dontMock ()控制哪些應該或者不應該進行 Mock。

來自社群的反應絕大部分都很正面。在 Hacker News,使用者 Cthulu 說

看起來很有趣:我們現在的 AngularJS 專案的測試套件越來越慢,部分原因是逐漸增加的測試,但主要的效能瓶頸是:

  • 沒有並行,即使測試套件全部是獨立的;
  • DOM 測試,導致大量的 GC 暫停;
  • (可能是)PhantomJS 啟動和初始化(未度量)。

我已經做了簡單的優化,將我的那些測試分成兩半,開兩個終端執行(開發時和持續測試中),但它看來有點玄。

直接應對依賴注入和 AngularJS,Facebook 說:“Jest 使用不同的方法來達到相同的結果。”對於 Angular,依賴作為引數進行傳遞,因此測試很容易寫。然而,Facebook 指出,為了 Angular 中函式的可測性,開發者必須遵循其特定模式,將其傳遞給 Angular 的依賴注入框架。Jest 的解決方案略有不同:

Jest 也能以 Angular 相同的方式 Mock 依賴,但它使用 CommonJS,而不是構建一個特定的模組載入器。這讓你能夠測試任何使用 CommonJS 的現有程式碼,不需要重度重構以使其相容其它模組系統。

使用者 Caiob 認同關於 Jest 的樂觀情緒,他也是這種依賴注入方法的擁護者,他說:“Facebook 能夠提升像 Jasmine 這樣的現有/熟悉的工具,這非常棒。並且,我喜歡他們處理 CommonJS 模組的方式。”

Morrison 說,通過 Jest,Facebook 希望開始這樣一種趨勢,讓測試變得更簡單,讓開發者有更多時間開發應用。InfoQ 讀者如果想參與這個專案,可以檢出 Github 庫併傳送 Pull 請求,或者在 Freenode 加入#jestjs。

相關文章