對于開發者,測試的重要性毋庸置疑, 所謂”無測試不上線“,”無測試不重構“等。但在實踐的過程中,測試總是有這樣的那樣的問題,随便列舉下:
不寫測試。一般是覺得寫測試浪費時間,也有可能是不會寫;
亂寫測試。随意的寫,沒有規範,沒有覆寫率,沒有內建;
寫了跟沒寫一樣。這樣的測試通常是不可讀、不可維護、不可信任,不可重複或獨立運作(強依賴某些特定的環境或條件)、不執行(通常隻是開發的時候執行一下,之後再也不會執行,或者執行太慢,沒有人願意執行)。
一千個人眼中有至少二千種測試理念或方法,很難定義什麼是一種好的測試。在團隊一直負責測試的推進,我們的理念很簡單,包括以下幾個原則:
覆寫75%+
一個好的測試,最重要的衡量标準就是測了多少(覆寫率),75%是最低的标準。這個标準對java來說基本可行,但對nodejs不太适用,javascript是弱類型的、動态語言,沒有編譯階段,很多錯誤隻能在運作時才會被發現,是以需要更高的覆寫率,最好是100%,目前個人的标準是90%+。
可重複執行
每一個測試用例,無論在任何環境下,都應該可以反複執行,并産生相同的結果。隻有這樣,才能夠相任你的測試,進而發現真正的bug。這也是內建測試最低要求。
保持獨立
一個測試用例隻測試代碼的某一方面,如一個分支,且不強依賴某些特定的環境或條件。
可讀、可維護、可信任
快快快
無論是單個測試用例,還是內建測試,必須要保證測試執行足夠的快。
又是一個非常大的話題,本文僅從個人角度給出nodejs測試的工具及方法。
nodejs 測試架構衆多,目前使用最廣的是mocha。本文詳細說明下 mocha, 并簡要介紹幾種其它架構。本文的示例,如無特别說明,都是基于mocha.
a simple, flexible, fun javascript test framework for node.js and the browser.
mocha 是一個功能豐富的javascript測試架構,它能運作在node.js和浏覽器中,支援bdd、tdd式的測試。
安裝
寫一個簡的測試用例
運作
輸出結果如下:
mocha 允許你使用任何你想用的斷言庫,包括:
mocha 提供了 <code>before()</code>, <code>after()</code>, <code>beforeeach()</code>, <code>aftereach()</code>等 hooks,用于設定前置條件及清理測試,示例如下:
專用測試允許隻測試指定的測試集或用例,隻需在測試集或用例前加<code>.only()</code>,示例如下:
跳過類似于 junit 的 <code>@ignore</code>, 用于跳過或忽略指定的測試集或用例,隻需在測試集或用例前加<code>.skip()</code>,示例如下:
textmate
jetbrains
wallaby.js
emacs
安裝 nodejs 插件(如果沒有安裝的話,預設intellij idea, webstorm都已安裝):通過 preferences > plugins 查找名為 <code>nodejs</code> 的插件并安裝;
添加 mocha 測試。通過 <code>edit configuration</code> 添加 <code>mocha</code>, 示例如下:
運作或調試。支援按目錄、檔案、測試集、測試用例等運作或調試,運作示例如下:
以下列舉幾個基于 nodejs 的測試架構或工具,它們可用于 nodejs 或 浏覽器端javascript 代碼的測試,不在本文讨論範圍,詳見官方文檔。
a behavior driven development javascript testing framework
jasmine is a behavior-driven development framework for testing javascript code. it does not depend on any other javascript frameworks. it does not require a dom. and it has a clean, obvious syntax so that you can easily write tests.
to bring a productive testing environment to developers
the main goal for karma is to bring a productive testing environment to developers. the environment being one where they don't have to set up loads of configurations, but rather a place where developers can just write the code and get instant feedback from their tests.
mocha 提供了測試的基本架構,在特定的場景下的測試還需要其它工具做以輔助,這個列舉幾個常用的工具。
the motivation with this module is to provide a high-level abstraction for testing http, while still allowing you to drop down to the lower-level api provided by super-agent.
簡單的 http 請求
上傳檔案
修改響應頭或體
代碼覆寫(code coverage)是軟體測試中的一種度量,描述程式中源代碼被測試的比例和程度,所得比例稱為代碼覆寫率。它有四個測量次元:
行覆寫率(line coverage):是否每一行都執行了
函數覆寫率(function coverage):是否每個函數都調用了
分支覆寫率(branch coverage):是否每個if代碼塊都執行了
語句覆寫率(statement coverage):是否每個語句都執行了
最簡單的方式:
輸出運作結果:
這條指令同時還生成了一個 <code>coverage</code> 子目錄,其中的 <code>coverage.json</code> 檔案包含覆寫率的原始資料,<code>coverage/lcov-report</code> 是可以在浏覽器打開的覆寫率報告,如下圖所示:
常見的測試模式包括tdd, bdd。
測試驅動開發是靈活開發中的一項核心實踐和技術,也是一種設計方法論。tdd的原理是在開發功能代碼之前,先編寫單元測試用例代碼,測試代碼确定需要編寫什麼産品代碼。tdd的基本思路就是通過測試來推動整個開發的進行,但測試驅動開發并不隻是單純的測試工作,而是把需求分析,設計,品質控制量化的過程。整體流程如下:
以一個階乘的小程式為例。先寫出的測試用例,如下所示。此時運作肯定會報錯,因為被測試的程式還沒有寫。
開始寫階乘的邏輯,如下所示。
此時再運作之前的測試用例,看其是否通過,如果全部通過則表示開發完成,如不通過則反複修改被測試的邏輯,直到全部的通過為止。
行為驅動開發是一種靈活軟體開發的技術,它鼓勵軟體項目中的開發者、qa和非技術人員或商業參與者之間的協作。主要是從使用者的需求出發,強調系統行為。其最顯著的特征是,通過編寫行為和規格說明來驅動軟體開發。行為和規格說明看上去與測試十分相似,但它們之前還是有顯著的不同。
還是以上面的階乘為例,bdd模式的測試用例如下:
從示例上看,bdd的測試用例與tdd最大的不同在于其措辭,bdd讀起來更像是一個句子。是以bdd的測試用例可作為開發者、qa和非技術人員或商業參與者之間的協同工具,對開發者來說,如果你可以非常流暢地讀測試用例,自然能夠寫出更好、更全面的測試。
tdd和bdd本質和目标都是一緻的。隻是在實施方法上,進行了不同的探讨來完善整個靈活開發的體系。tdd的疊代反複驗證是靈活開發的保障,但沒有明确如何根據設計産生測試,并保障測試用例的品質,而bdd倡導大家都用簡潔的自然語言描述系統行為的理念,恰好彌補了測試用例(即系統行為)的準确性。
幾乎所有基于nodejs的庫或應用都選擇了bdd, 至于為什麼,我還沒有搞明白。
目前比較流行的斷言庫包括:
這些斷言庫除了風格上略有不同外,實作在功能幾乎完全一緻,可根據個人喜好或應用需求選擇。